仍在学习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),这将破坏lambda
的item
自变量。
最后,我希望在连接信号时使用新的语法——旧的语法非常容易出错,而且远没有那么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))