Проблемы с пониманием сигнала Mapper PyQt

Поэтому я создаю меню опций на основе некоторых файлов в моей системе. У меня есть список объектов, для которых мне нужно динамически сгенерировать опцию в меню, и я должен быть в состоянии сообщить функции, которая выполняет создание, знать, какой объект использовать. После некоторых исследований я нашел пост ниже. Я не мог прокомментировать, так как моя репутация еще не высока: как передать аргументы функциям обратного вызова в 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)

Я использую соединения нового стиля неправильно?

Основываясь на этом посте, а также на исходной ссылке, которую я разместил, я решил, что все делаю правильно.

1 ответ

Исходный пример кода (который я написал) прекрасно работает для меня, используя Python2 или Python3 с несколькими различными последними версиями PyQt4. Однако, если я использую действительно старую версию PyQt4 (4.7), обработчик больше не вызывается.

Причина (и решение) этого дана в ответе на сообщение в списке рассылки, на которое вы ссылаетесь:

На самом деле это проблема с вызовом QSignalMapper.map() из прокси, а не из соединений нового стиля.

Обходной путь должен явно указать сигнал, который совместим с map()...

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

Сегодняшний снимок PyQt будет разумнее найти пригодный для использования слот Qt, прежде чем решить, что ему нужно использовать прокси, чтобы обходной путь не потребовался.

Есть несколько сигналов (например, clicked а также triggered), который всегда отправляет значение по умолчанию, если вы явно не запросите иначе. С сигналами старого стиля вы можете указать перегрузку по умолчанию без SIGNAL("triggered()"), но с сигналами нового стиля, вы должны сделать это так:

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

Но это необходимо только для очень старых версий PyQt4 - основная проблема была исправлена ​​еще в 2010 году (точная версия неизвестна, но с версией 4.8 все должно быть в порядке).

Другие вопросы по тегам