pyqt动态生成QMenu操作并连接



仍在学习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()

您的代码几乎是正确的。您只需要将信号连接到具有默认参数的lambda,如下所示:

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

默认参数确保每个lambda都获得当前循环变量的副本。还要注意,还需要一个初始chk参数。这是因为默认情况下,triggered信号发送其当前检查状态(true或false),这将破坏lambdaitem自变量。

最后,我希望在连接信号时使用新的语法——旧的语法非常容易出错,而且远没有那么Python。

我试着纠正了第一篇文章中给出的例子。这是一个工作版本。右键单击按钮,选择一个项目,它将在您的终端中打印:

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.popMenu.addAction('Selected %s' % item)
        action.triggered[()].connect(
            lambda item=item: self.printItem(item))
        self.popMenu.exec_(self.button.mapToGlobal(point))
    @QtCore.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()

如果我理解得对:

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))

相关内容

  • 没有找到相关文章

最新更新