使用QtDesigner的pyQt信号/槽

4 投票
1 回答
3241 浏览
提问于 2025-04-17 02:54

我正在尝试写一个程序,让它能和QGraphicsView互动。我想在QGraphicsView里收集鼠标和键盘的事件。比如说,当用户点击QGraphicsView这个小部件时,我想获取鼠标的位置,类似这样的功能。我可以很简单地把这些代码写死,但我想用QtDesigner,因为我的界面会经常变化。

这是我在gui.py里的代码。里面有一个简单的小部件,包含了QGraphicsView。

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_graphicsViewWidget(object):
    def setupUi(self, graphicsViewWidget):
        graphicsViewWidget.setObjectName(_fromUtf8("graphicsViewWidget"))
        graphicsViewWidget.resize(400, 300)
        graphicsViewWidget.setMouseTracking(True)
        self.graphicsView = QtGui.QGraphicsView(graphicsViewWidget)
        self.graphicsView.setGeometry(QtCore.QRect(70, 40, 256, 192))
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))

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

    def retranslateUi(self, graphicsViewWidget):
        graphicsViewWidget.setWindowTitle(QtGui.QApplication.translate("graphicsViewWidget", "Form", None, QtGui.QApplication.UnicodeUTF8))

这是程序的代码:

#!/usr/bin/python -d

import sys
from PyQt4 import QtCore, QtGui
from gui import Ui_graphicsViewWidget

class MyForm(QtGui.QMainWindow):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_graphicsViewWidget()
        self.ui.setupUi(self)
        QtCore.QObject.connect(self.ui.graphicsView, QtCore.SIGNAL("moved"), self.test)

    def mouseMoveEvent(self, event):
        print "Mouse Pointer is currently hovering at: ", event.pos()
        self.emit(QtCore.SIGNAL("moved"), event)

    def test(self, event):
        print('in test')

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())

当我运行这段代码时,结果却和我想要的正好相反。我得到的鼠标位置在其他地方,而不是在QGraphicsView里面。

我确定问题出在我的QObject.connect上。但是每次我回去看关于信号和槽的内容时,虽然理解了,但就是无法实现。

请帮帮我,我这几天一直在为这个问题苦恼。如果之前有人问过这个问题,我很抱歉,但我已经看过所有相关的讨论,还是没找到解决办法。

谢谢!

1 个回答

3

信号必须来自于在界面设计中定义的 QGraphicsView 对象。

你可以这样创建一个从 QGraphicsView 继承的类:

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyView(QGraphicsView):
    moved = pyqtSignal(QMouseEvent)

    def __init__(self, parent = None):
        super(MyView, self).__init__(parent)

    def mouseMoveEvent(self, event):
        # call the base method to be sure the events are forwarded to the scene
        super(MyView, self).mouseMoveEvent(event)

        print "Mouse Pointer is currently hovering at: ", event.pos()
        self.moved.emit(event)

然后,在设计器中:

  • 右键点击 QGraphicsView,然后选择 提升为
  • 提升的类名 字段中输入类的名称(比如 "MyView"),
  • 头文件 字段中输入这个类所在的文件名,但不要加 .py 后缀,
  • 点击 添加 按钮,然后点击 提升 按钮。

最后,你可以用 pyuic4 重新生成你的文件 gui.py

撰写回答