【问题标题】:pyQt signals/slots with QtDesigner带有 QtDesigner 的 pyQt 信号/插槽
【发布时间】:2011-11-23 08:52:54
【问题描述】:

我正在尝试编写一个与 QGraphicsView 交互的程序。我想在 QGraphicsView 中发生事件时收集鼠标和键盘事件。例如,如果用户单击 QGraphicsView 小部件,我将获得鼠标位置,类似的东西。我可以很容易地对其进行硬编码,但我想使用 QtDesigner,因为 UI 会经常更改。

这是我用于 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 的问题。但是每次我回去阅读有关信号和插槽的内容时,它都是有道理的,但我无法理解。

请帮忙,过去几天我一直在敲我的头。很抱歉,如果之前有人问过这个问题,但我已经阅读了有关该主题的所有主题,但我无处可去。

谢谢

【问题讨论】:

  • 在您的 gui.py 文件中,self.graphicsView = MyForm(graphicsViewWidget) 行会引发异常,因为未定义 MyForm。我不确定你到底想在那里做什么。你能修好那条线吗?
  • 对不起,MyForm 应该是 QtGui.QGraphicsView。我在线程中修复它并在我的计算机上运行它现在应该可以工作了。
  • 作为建议,如果您使用from PyQt4.QtGui import *from PyQt4.QtCore import * 导入,您可以删除所有QtCore.QtGui. 的实例,使代码更具可读性。
  • 感谢 Blender 的好建议,我会记住这一点

标签: python pyqt4 signals qt-designer slots


【解决方案1】:

信号必须来自 ui 中定义的 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,然后升级为
  • Promoted Class Name字段中写入类名(例如“MyView”),
  • 头文件字段中写入该类所在的文件名,但不带.py扩展名,
  • 点击添加按钮,然后点击推广按钮。

您可以使用 pyuic4 重新生成您的文件 gui.py

【讨论】:

  • 非常好的解释,谢谢 :) 我只有一个小问题,是否有可能让 QtDesigner 知道您在文件中创建了哪些插槽/信号(或相反)。必须定义它们 2 次似乎毫无意义。
  • @WoLpH 我猜你可以创建一个插件(like that,但如果你只在一个项目中使用这个类,这似乎很复杂。
  • 感谢您的建议,在这种情况下,插件可能比它们的价值更麻烦。但是现在集成起来非常容易,所以我将它们混合在一起:)
猜你喜欢
  • 2012-07-13
  • 2013-10-22
  • 2011-08-16
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多