还在学习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()
答案 0 :(得分:14)
您的代码几乎是正确的。您只需要使用默认参数将信号连接到lambda
,如下所示:
for item in testItems:
action = self.popMenu.addAction('Selected %s' % item)
action.triggered[()].connect(
lambda item=item: self.printItem(item))
默认参数确保每个lambda
获取当前循环变量的副本。另请注意,空元组用于指定triggered
信号。如果没有这样做,triggered
信号默认会发送一个布尔值,这会破坏item
的{{1}}参数。
最后,我希望在连接信号时使用new-style syntax - 旧样式可能非常容易出错,并且远不如pythonic。
答案 1 :(得分: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))
答案 2 :(得分: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.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()