6

まだpyqtの仕組みを学んでいます。customContextMenu を動的に生成し、関数に接続したいと考えています。これまでのところ、次のようになりましたが、接続部分が機能しませんか?

import sys
from PyQt4 import QtGui, QtCore

class MainForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

    # create button
    self.button = QtGui.QPushButton("test button", self)       
    self.button.resize(100, 30)

    # set button context menu policy
    self.button.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    self.connect(self.button, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menu)
    self.popMenu = QtGui.QMenu(self)

    def on_context_menu(self, point):
        self.popMenu.clear()

        #some test list for test
        testItems = ['itemA', 'itemB', 'itemC']
        for item in testItems:
            action = self.btn_selectPyFilterPopMenu.addAction("Selected %s" % item)
            self.connect(action,QtCore.SIGNAL("triggered()"),self,QtCore.SLOT("printItem('%s')" % item))    
        self.popMenu.exec_(self.button.mapToGlobal(point))

    @pyqtSlot(str)
    def printItem(self, item):
        print item

def main():
    app = QtGui.QApplication(sys.argv)
    form = MainForm()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()
4

3 に答える 3

17

あなたのコードはほぼ正しいです。lambda次のように、デフォルトの引数を使用してシグナルを に接続するだけです。

    for item in testItems:
        action = self.popMenu.addAction('Selected %s' % item)
        action.triggered.connect(
            lambda chk, item=item: self.printItem(item))

デフォルトの引数は、それぞれが現在のループ変数lambdaのコピーを取得することを保証します。また、初期引数も必要であることに注意してください。これは、シグナルがデフォルトで現在のチェック状態 (true または false) を送信するためです。chktriggereditemlambda

最後に、シグナルを接続するときに新しいスタイルの構文を使用することをお勧めします。古いスタイルは非常にエラーが発生しやすく、pythonic ではありません。

于 2013-12-05T06:10:45.797 に答える
1

私があなたを正しく理解していれば:

import sys
from PyQt4 import QtGui, QtCore

class MainForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

    # create button
    self.button = QtGui.QPushButton("test button", self)       
    self.button.resize(100, 30)

    # set button context menu policy
    self.button.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    self.customContextMenuRequested.connect (self.on_context_menu)

    def on_context_menu(self, point):

        popMenu = QtGui.QMenu(self)

        #some test list for test
        testItems = ['itemA', 'itemB', 'itemC']

        #
        for item in testItems:
            action = QtGui.Action(item)
            action.triggered.connect(lambda x: print item)

        popMenu.exec_(self.button.mapToGlobal(point))
于 2013-12-05T02:41:30.407 に答える