PyQt5 - 在 QMainMenu 中,如何使 QWidget 成为父级(临时)? [英] PyQt5 - in a QMainMenu, how to make a QWidget the parent (temporarily)?

查看:45
本文介绍了PyQt5 - 在 QMainMenu 中,如何使 QWidget 成为父级(临时)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 QWidget 初始化的 QMainWindow.我希望每次按下按钮 New 在我的 QMainWiindow 中,它会暂时打开 QWidget(在我的情况下,直到鼠标按钮释放).

I have a QMainWindow that I initialize with a QWidget. I want that each Time I'll press the button New In my QMainWiindow, it will open the QWidget temporarily (in my case, until mouse button release).

我在将 QMainWindowQWidget 交互时遇到问题.我尝试了很多选项,但似乎我尝试的所有方法都将 QWidget 绑定到 QMainWindow 屏幕,而我不想要那样.

I'm having trouble interacting QMainWindow with the QWidget. I tried many options, but it seemed like everything I tried tied the QWidget to the QMainWindow screen, and I don't want that.

举个例子会更容易:

TempWidgetMenu.py 是我的 QMainWindow 类.当我按下 New 时,会出现一个 QWidget,它会将屏幕染成灰色,并将从按下按钮到按钮释放的矩形上色(如窗口截图工具).

TempWidgetMenu.py is my QMainWindow class. When I press New, a QWidget will appear, it Will color the screen gray-ish, and will color a rectangle from a button press, to the button release (like in windows snipping tool).

我希望每次按下 New 时,我都能从屏幕的每个点绘制一个矩形,第一次也是如此.当我第二次(或之后)按 New 时,它会为除主菜单屏幕之外的所有内容着色,并且不会响应按钮操作.

I Want that that every time I press on New, I'll be able to draw a rectangle from every point of the screen, and so it does the first time. When I press New for the second time (or afterwards), it will color everything but the main menu screen, and will not respond to the button actions.

我希望每次按下按钮时小部件都成为屏幕中程序的父级".

I want the widget to be the "parent" of the program in the screen every time I press the button.

TempWidgetMenu.py(主要):

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction
from PyQt5.QtGui import QPixmap, QPainter
import TempWidget


class Menu(QMainWindow):

    def __init__(self):
        super().__init__()
        newAct = QAction('New', self)
        newAct.triggered.connect(self.new_image_window)
        self.toolbar = self.addToolBar('Exit')
        self.toolbar.addAction(newAct)
        self.opac_rect = TempWidget.TempOpacWidget()
        self.image = QPixmap("background.png")
        self.setGeometry(100, 100, 500, 300)
        self.resize(self.image.width(), self.image.height())
        self.show()

    def new_image_window(self):
        self.opac_rect.start()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self.image)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainMenu = Menu()
    sys.exit(app.exec_())

TempWidget.py:

import tkinter as tk
from PyQt5 import QtWidgets, QtCore, QtGui


class TempOpacWidget(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()
        root = tk.Tk()
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()
        self.setGeometry(0, 0, screen_width, screen_height)
        self.setWindowTitle(' ')
        self.begin = QtCore.QPoint()
        self.end = QtCore.QPoint()
        self.busy = False

    def start(self):

        self.busy = True
        self.setWindowOpacity(0.3)
        self.show()

    def paintEvent(self, event):
        if self.busy:
            brush_color = (128, 128, 255, 100)
            opacity = 0.3
        else:
            brush_color = (0, 0, 0, 0)
            opacity = 0

        self.setWindowOpacity(opacity)
        qp = QtGui.QPainter(self)
        qp.setBrush(QtGui.QColor(*brush_color))
        qp.drawRect(QtCore.QRectF(self.begin, self.end))

    def mousePressEvent(self, event):
        self.begin = event.pos()
        self.end = self.begin
        self.update()

    def mouseMoveEvent(self, event):
        self.end = event.pos()
        self.update()

    def mouseReleaseEvent(self, event):
        self.busy = False
        self.repaint()

我意识到我在开始时初始化了 TempOpacWidget 一次.我只想初始化一次,因为它在做同样的事情.

I realize I'm initializing the TempOpacWidget once at the start. I want to initialize it only once, because it is doing the same thing.

我该如何解决,让 TempOpacWidget 成为我每次给他打电话时的父级?

How can I fix it, such that the TempOpacWidget will be the parent every time I call him?

如果有不清楚的地方,请运行代码,这将非常有意义.按New,选择一个矩形(用鼠标),然后再次按New选择另一个矩形,你就会明白是什么问题了.

If something is not clear, run the code it will make perfect sense. Press New, Choose a rectangle (with mouse), and then press New again to choose another rectangle, and you will understand what is the problem.

推荐答案

我不太明白会发生什么,但我添加并更改了一些代码行.单击New 按钮并绘制一个矩形.你应该有新的想法.祝你好运.

I do not quite understand what's going to happen, but I added and changed some lines of code. Click the New button and draw a rectangle. You should have new ideas. Good luck.

TempWidgetMenu.py

TempWidgetMenu.py

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction
from PyQt5.QtGui     import QPixmap, QPainter
from PyQt5.QtCore    import Qt                             # +++
import TempWidget

class Menu(QMainWindow):
    def __init__(self):
        super().__init__()
        newAct = QAction('New', self)
        newAct.triggered.connect(self.new_image_window)
        self.toolbar = self.addToolBar('Exit')
        self.toolbar.addAction(newAct)

        self.opac_rect = TempWidget.TempOpacWidget(self)   # +++ self

        self.imageShow()                                   # +++  

    def imageShow(self):
        self.setWindowFlags(Qt.WindowStaysOnTopHint)       # +++ 

        self.image = QPixmap("background.png")
        self.setGeometry(100, 100, 500, 300)
        self.resize(self.image.width(), self.image.height())
        self.show()

    def new_image_window(self):
        self.opac_rect.start()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self.image)

    # +++    
    def closeEvent(self, event):
        self.opac_rect.close()
        event.accept()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainMenu = Menu()
    sys.exit(app.exec_())

TempWidget.py

TempWidget.py

import tkinter as tk
from PyQt5        import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import Qt                                 # +++

class TempOpacWidget(QtWidgets.QWidget):

#    def __init__(self):
#        super().__init__()
    def __init__(self, parent=None):
        super(TempOpacWidget, self).__init__()              # no (parent)
        self.parent = parent                                # +++
        print("self=`{}`, \nparent=`{}`".format(self, self.parent))
        self.setWindowFlags(Qt.WindowStaysOnTopHint)        # +++

        root = tk.Tk()
        screen_width  = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()
        self.setGeometry(0, 0, screen_width, screen_height)
#        self.setWindowTitle('')
        self.begin = QtCore.QPoint()
        self.end   = QtCore.QPoint()
        self.busy  = False

    def start(self):
        self.setWindowFlags(Qt.WindowStaysOnTopHint)        # +++
        self.busy = True
        self.setWindowOpacity(0.5) # 0.3
        self.show()

    def paintEvent(self, event):
        if self.busy:
            brush_color = (128, 128, 255, 100)
            opacity = 0.5          # 0.3
        else:
            brush_color = (0, 0, 0, 0)

            opacity = 0.5          # 0       <<<---------
            # or try  `0`, how suits you !?  <<<---------
            #opacity = 0                    #<<<--------- 

        self.setWindowOpacity(opacity)
        qp = QtGui.QPainter(self)
        qp.setBrush(QtGui.QColor(*brush_color))
        qp.drawRect(QtCore.QRectF(self.begin, self.end))

    def mousePressEvent(self, event):
        #self.parent.hide()
        self.begin = event.pos()
        self.end   = self.begin
        self.update()

    def mouseMoveEvent(self, event):
        self.end = event.pos()
        self.update()

    def mouseReleaseEvent(self, event):
        print("def mouseReleaseEvent(self, event):---")
        self.busy = False
        self.repaint()
        self.parent.imageShow()                         # +++

这篇关于PyQt5 - 在 QMainMenu 中,如何使 QWidget 成为父级(临时)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆