python - 在 QtDesigner 生成的小部件中捕获事件
问题描述
我正在尝试制作一个应用程序,允许使用鼠标(添加、移动、调整大小等)操作 QGraphicsView/QGraphicScene 中的某些对象。UI 是从 QtDesigner 生成的。我搜索的所有示例都表明鼠标事件是在主应用程序类中处理的。但是,如果有更多处理鼠标事件的小部件,我认为将鼠标逻辑单独保留在这些小部件中是明智的。我试图用单独的类来遵循这个建议,但由于我的小部件是由设计师生成的,它似乎不起作用。
我的设计师生成的代码:
# 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 没有任何经验,也不完全理解子类化的概念(因为我认为这是应该这样做的方式)。
解决方案
未捕获事件的原因是因为在从 QtDesigner 文件生成的 .py 文件中,self.DesignWindowView
它仍然是一个QtWidgets.QGraphicsView
对象。对此的解决方案是将QtWidgets.QGraphicsView
Qt Designer 中的对象提升为DesignerWindowView
对象。
为此,最好将 的定义DesignerWindowView
放在一个单独的.py
文件中(例如designerwindowview.py
),以防止主.py
文件和.py
从 QtDesigner 文件生成的文件之间的循环依赖。
在设计器中,右键单击要推广的小部件并选择Promote to ...
。填写提升的类名 ( DesignerWindowView
)。对于头文件的名称,您应该使用不带.py
扩展名的提升类的定义填写 .py 文件的名称(例如designerwindowview
)。
保存并pyuic5
像以前一样运行。在生成的 .py 文件 self.DesignWindowView
中现在应该是一个DesignWindowView
对象,并且应该有一个类似于文件from designwindowview import DesignWindowView
底部的导入语句.py
。
推荐阅读
- linux - 如何在 shell 脚本中获取特定文件夹的文件名列表?
- python - 当不同列中的值在两个值之间时,Python需要获取一列数据的平均值或平均值
- angular - Angular 11:尝试使用 combineLatest 为对象赋值
- openapi - 基于 Maven 的示例引发异常
- mysql - 带有正则表达式的 MySQL 查询
- erlang - erlang 的 `binary_to_term` 是否总是能够读取任何以前版本的二进制 `term_to_binary` 生成的?
- angular - 为什么 app_initializer 无法导航到另一个组件,但其他一切正常?
- wordpress - 商店页面上的额外产品信息
- php - 如何使用 Zend 扩展和 PHP 内置服务器
- r - R - 按行和列合并数据框