如何确定哪个小部件发出了信号

How to determine which widget emitted the signal

提问人:Marc B. Hankin 提问时间:6/5/2019 最后编辑:eyllanescMarc B. Hankin 更新时间:6/5/2019 访问量:3766

问:

我想使 QlineEdit 字段可双击,以便用户双击 QlineEdit 字段(例如,“qle01”)调用一个函数。 该函数应该能够通过“名称”来标识向函数发送信号的 QLineEdit 对象。

我不知道在下面的示例代码中,“name”是否是描述“qle01”和“qle02”的正确词。也许更好的术语是“句柄”。

在下面的脚本中,如果双击 qle01,我的目标是打印第 9 行,“QLineEdit 字段的名称是'qle01'”。我希望能帮助弄清楚如何使第 9 行打印“QLineEdit 字段的名称是'qle01'”。

在应得的信用额度上提供信用额度,除了我在第 9 行的伪代码外,下面的其余编码来自使用 QLineEdit 在 mouseDoubleClickEvent 的 StackOverflow 发布中的示例 1

import sys

from PyQt4 import QtGui

class LineEdit(QtGui.QLineEdit):
    def mouseDoubleClickEvent(self, event):
        print("pos: ", event.pos())
        # The next line is pseudo-code, because I don't know how to properly code it
        print("The QLineEdit field's name is '" + ['qle01' or 'qle02'] + "'") # i.e., depending on which of the 
                                                                       # QLineEdit fields was double-clicked  

class Widget(QtGui.QWidget):
    def __init__(self, *args, **kwargs):
        QtGui.QWidget.__init__(self, *args, **kwargs)
        qle01 = LineEdit()
        qle02 = LineEdit()
        lay = QtGui.QVBoxLayout(self)
        lay.addWidget(qle01)
        lay.addWidget(qle02)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

我有一些关于如何将句柄或名称传递给插槽/函数的想法,但我没有得到任何有用的地方。

  1. 一个想法是让 QLineEdit 字段的信号将字段的 QWidget.effectiveWinId(窗口系统标识符)发送到功能槽,但我无法弄清楚如何访问 QWidget.effectiveWinId。

  2. 另一个想法是使用我在许多帖子和教程中看到的 sender() 函数(例如,如何确定谁发出了信号?我尝试使用 sender() 函数,如下所示:

    class ObjectName(object):
    @QtCore.pyqtSlot()
    def __getattribute__(self, name):
        print "getting `{}`".format(str(name))
        print('str(self.sender()) = ' + str(self.sender()))      
    

但是最后一行产生了这个输出:str(self.sender()) = None。

我在位于 https://www.riverbankcomputing.com/static/Docs/PyQt4/ 的 PyQt4 参考指南下找不到对 sender() 函数的任何引用。所以我不理解 sender() 函数,我显然不知道如何使用它。

所以,最重要的是,我希望能帮助弄清楚如何使第 9 行打印“QLineEdit 字段的名称是'qle01'”。

蟒蛇 PyQT pyqt4

评论


答:

4赞 eyllanesc 6/5/2019 #1

变量的名称不标识对象,例如在以下代码中:

qle01 = LineEdit()
foo_name = qle01

标识 QLineEdit 的变量的名称是什么?好吧,qle01 和 foo_name,因为两者都是内存空间的别名。

可以做的是标识对象,使指向同一对象的所有变量都具有相同的 id。

另一方面,最好实现一个信号来通知是否在 QLineEdit 中进行了双击,因为这将允许我们通过 QObject 的 sender() 方法获取对象。

import sys

from PyQt4 import QtCore, QtGui


class LineEdit(QtGui.QLineEdit):
    doubleClicked = QtCore.pyqtSignal()

    def mouseDoubleClickEvent(self, event):
        self.doubleClicked.emit()
        super(LineEdit, self).mouseDoubleClickEvent(event)


class Widget(QtGui.QWidget):
    def __init__(self, *args, **kwargs):
        super(Widget, self).__init__(*args, **kwargs)
        self.qle01 = LineEdit(doubleClicked=self.on_doubleClicked)
        self.qle02 = LineEdit(doubleClicked=self.on_doubleClicked)
        lay = QtGui.QVBoxLayout(self)
        lay.addWidget(self.qle01)
        lay.addWidget(self.qle02)

    @QtCore.pyqtSlot()
    def on_doubleClicked(self):
        if self.sender() is self.qle01:
            print("The QLineEdit field's name is 'qle01'.")
        elif self.sender() is self.qle02:
            print("The QLineEdit field's name is 'qle02'.")


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

评论

0赞 Marc B. Hankin 6/7/2019
非常感谢!我有一个相关的问题,如果你有时间回答。在哪里可以找到 sender() 函数的技术参考?我无法在此网址下找到它: riverbankcomputing.com/static/Docs/PyQt4/index.html 我想找到技术参考,以便我更多地了解如何使用 sender() 函数。
0赞 eyllanesc 6/7/2019
@user235218 PyQt4 的文档与 Qt4 的文档类似,因为它是一个包装器,所以请检查 doc.qt.io/archives/qt-4.8/qobject.html#sender
0赞 Marc B. Hankin 6/19/2019
谢谢。在您的帮助下,我在以下位置找到了它: riverbankcomputing.com/static/Docs/PyQt4/qobject.html#sender