无法理解Signal Mapper PyQt

时间:2015-05-25 16:08:53

标签: python pyqt qsignalmapper

所以我根据系统中的一些文件生成一个选项菜单。我有一个对象的列表列表,我需要在菜单中动态生成一个选项,并且需要能够让正在创建的函数知道要使用哪个对象。经过一番研究后,我发现了以下帖子。由于我的代表不高,我无法发表评论: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)

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

基于this post以及我发布的original link,我认为我做得很对。

1 个答案:

答案 0 :(得分:1)

最初的示例代码(我写的)对我来说非常好用,使用Python2或Python3以及几个不同的PyQt4版本。但是,如果我使用的是旧版本的PyQt4(4.7),则不再调用处理程序。

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

  

从a调用QSignalMapper.map()实际上是一个问题   代理而不是新式的连接。

     

解决方法是明确指定兼容的信号   with map()...

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

Tonight的PyQt快照将更加智能地找到可用的Qt插槽   在决定它需要使用代理以便解决方法之前   没有必要。

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

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

但这只是非常旧版本的PyQt4所必需的 - 基本问题在2010年得到修复(不知道确切的版本,但4.8应该没问题。)