在QtDesigner生成的小部件中捕获事件

时间:2019-09-08 13:27:34

标签: python pyqt5 qt-designer

我正在尝试制作一个允许使用鼠标在QGraphicsView / QGraphicScene中操作某些对象的应用程序(添加,移动,调整大小等)。 UI是从QtDesigner生成的。 我搜索过的所有示例都表明,鼠标事件是在主应用程序类中处理的。但是,如果有更多处理鼠标事件的小部件,我认为将鼠标逻辑分别保留在这些小部件中是明智的。 我尝试在单独的类中遵循this的建议,但是由于我的窗口小部件是由设计人员生成的,因此似乎无效。

我的设计师生成的代码:

# Created by: PyQt5 UI code generator 5.13.0

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.DesignWindowView = QtWidgets.QGraphicsView(self.centralwidget)
        self.DesignWindowView.setGeometry(QtCore.QRect(20, 20, 761, 501))
        self.DesignWindowView.setObjectName("DesignWindowView")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

主文件:

import sys
from PyQt5 import QtWidgets, uic, QtGui, QtCore
from Ui_MainWindow import Ui_MainWindow

class DesignWindowView(QtWidgets.QGraphicsView):

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            print("Press on DesignWindowView!")

    def mouseMoveEvent(self, event):
        print("Mouse on DesignWindowView")

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self, *args, obj=None, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setupUi(self)

        DesignWindowScene = QtWidgets.QGraphicsScene()
        DesignWindowScene.addSimpleText("The Text")
        self.DesignWindowView.setScene(DesignWindowScene)
        self.DesignWindowView.setCursor(QtCore.Qt.CrossCursor)
        self.setMouseTracking(True)
        self.DesignWindowView.setMouseTracking(True)

        self.show()

app = QtWidgets.QApplication(sys.argv)
# load MainWindow design
mainwindow = MainWindow()
# start the UI's event loop
app.exec_()

DesignWindowView类将负责从QtDesigner生成的小部件,但这显然行不通,并且没有捕获任何鼠标事件。 我没有OOP的经验,也没有完全理解子类化的概念(因为我认为这是应该这样做的方式)。

1 个答案:

答案 0 :(得分:0)

未捕获事件的原因是因为在QtDesigner文件生成的.py文件中,self.DesignWindowView仍然是QtWidgets.QGraphicsView对象。解决方案是将Qt Designer中的QtWidgets.QGraphicsView升级为DesignerWindowView对象。

为此,最好将DesignerWindowView的定义放在单独的.py文件(例如designerwindowview.py)中,以防止主.py文件和{从QtDesigner文件生成的{1}}文件。

在设计器中,右键单击要升级的窗口小部件,然后选择.py。填写升级的班级名称(Promote to ...)。对于头文件的名称,您应该使用不带DesignerWindowView扩展名(例如.py)的升级类的定义来填充.py文件的名称。

像以前一样保存并运行designerwindowview。在生成的.py文件中,pyuic5现在应该是一个self.DesignWindowView对象,并且在DesignWindowView文件的底部应该有一个类似于from designwindowview import DesignWindowView的import语句。