1

所以我正在根据我系统上的一些文件生成一个选项菜单。我有一个对象列表,我需要在菜单中动态生成一个选项,并且需要能够让正在创建的函数知道要使用哪个对象。经过一番研究,我找到了下面的帖子。我无法发表评论,因为我的代表还不高:How to pass arguments to callback functions in PyQt

当我运行它时,信号映射器无法正常工作。它甚至没有正确调用handleButton。关于如何正确使用信号映射器的任何想法?

from PyQt4 import QtGui, QtCore

class Window(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.mapper = QtCore.QSignalMapper(self)
        self.toolbar = self.addToolBar('Foo')
        self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly)
        for text in 'One Two Three'.split():
            action = QtGui.QAction(text, self)
            self.mapper.setMapping(action, text)
            action.triggered.connect(self.mapper.map)
            self.toolbar.addAction(action)
        self.mapper.mapped['QString'].connect(self.handleButton)
        self.edit = QtGui.QLineEdit(self)
        self.setCentralWidget(self.edit)

    def handleButton(self, identifier):
        print 'run'
        if identifier == 'One':
            text = 'Do This'
            print 'Do One'
        elif identifier == 'Two':
            text = 'Do That'
            print 'Do Two'
        elif identifier == 'Three':
            print 'Do Three'
            text = 'Do Other'
        self.edit.setText(text)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(300, 60)
    window.show()
    sys.exit(app.exec_())

编辑:

我发现通过使用旧式信号/插槽连接,这是固定的:

#action.triggered.connect(self.mapper.map)
self.connect(action, QtCore.SIGNAL("triggered()"), self.mapper, QtCore.SLOT("map()"))

#self.mapper.mapped['QString'].connect(self.handleButton)
self.connect(self.mapper, QtCore.SIGNAL("mapped(const QString &)"), self.handleButton)

我是否错误地使用了新型连接?

基于这篇文章以及我发布的原始链接,我认为我做的事情是正确的。

4

1 回答 1

1

原始示例代码(我编写的)对我使用 Python2 或 Python3 以及几个不同的 PyQt4 最新版本非常有效。但是,如果我使用真正旧版本的 PyQt4 (4.7),则不再调用处理程序。

对此的原因(和解决方案)在对您链接到的邮件列表帖子的回复中给出:

这实际上是从代理而不是新型连接调用 QSignalMapper.map() 的问题。

解决方法是显式指定与 map() 兼容的信号...

self.b1.clicked[()].connect(self.mapper.map)

今晚的 PyQt 快照将更聪明地找到一个可用的 Qt 插槽,然后再决定它需要使用代理,这样就不需要变通方法了。

有一些信号(如clickedtriggered)总是发送一个默认值,除非你明确要求。对于旧式信号,您可以使用 指定无默认重载SIGNAL("triggered()"),但对于新式信号,您必须这样做:

    action.triggered[()].connect(self.mapper.map)

但这仅对非常旧版本的 PyQt4 是必要的——基本问题早在 2010 年就已修复(不知道确切的版本,但 4.8 应该没问题)。

于 2015-05-25T19:45:46.870 回答