PyQt5 - in a QMainMenu, how to make a QWidget the parent (temporarily)?

只愿长相守 提交于 2019-12-02 09:57:17

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

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

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()                         # +++

If I understand you correctly, you want Menu.opac_rect to open in a separate window while your mouse button is pressed. I see a couple of issues with this. First, if you want a QWidget to open in a separate window, you should pass a Qt.windowFlags argument to the QWidget constructor, i.e.

self.opac_rect = TempWidget.TempOpacWidget(None, QtCore.Qt.Window)

Don't forget to import the QtCore namespace.

Secondly, QAction doesn't have the signals you need. Only objects that inherit from QWidget will have mousePressEvent and mouseReleaseEvent. If you must keep things in the toolbar, QToolBar has QToolBar.addWidget, so you could use a QLabel instead of QAction, and overwrite the necessary event handlers.

self.opac_rect = TempWidget.TempOpacWidget(None, QtCore.Qt.Window)
newAct = QLabel('New')
newAct.mousePressEvent = lambda e: self.opac_rect.start()
newAct.mouseReleaseEvent = lambda e: self.opac_rect.stop() # You'll need to write this
self.toolbar.addWidget(newAct)

You'll probably have to fiddle with the QLabel styling to make it look right, but I think this will accomplish what you are looking for.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!