我在PyQT中使用一组动态创建的按钮时遇到了一些麻烦。
我正在使用列表来创建与不同值对应的按钮。因为每个按钮都不同,我需要让它们将参数传递给单独识别自己的“按钮单击”功能,这样我就可以用它们执行不同的操作。以下是我到目前为止的情况:
for x in self.buttons:
name = str(x)
button = QtGui.QPushButton(Frame)
button.setText(name)
cp_result = self.changeProject(name)
if cp_result is None:
print 'changeProject(%s) is None!', name
else:
print 'changeProject(%s) is OK (%r)', name, cp_result
#button.clicked.connect(cp_result)
setattr(self, "btn_%s" % name, button)
self.btnList.append(button)
def changeProject(self, name):
for x in self.btnList:
if x.isDown:
#Change UI Frame to blahblah
return 'A String'
使用Alex,这是最新的代码,在changeProject上测试一个返回值,它显然不能是一个字符串,但我仍然需要确定在自动生成的按钮之间按下了哪个按钮。
当前错误:TypeError: connect() slot argument should be a callable or a signal, not 'str'
答案 0 :(得分:1)
您可以使用setattr
for x in buttons:
name = str(x)
button = QtGui.QPushButton(Frame)
button.setText(name)
button.clicked.connect(self.changeProject(name))
setattr(self, "btn_%s" % name, button)
答案 1 :(得分:1)
错误消息告诉您的是self.changeProject("%s")
,其中一个值代替%s
None
返回changeProject
。大概你是想让那种方法返回不同的东西?
当然,在没有看到代码的情况下,进一步调试cp_result = self.changeProject(name)
if cp_result is None:
logging.error('changeProject(%s) is None!', name)
else:
logging.info('changeProject(%s) is OK (%r)', name, cp_result)
button.clicked.connect(cp_result)
的任务是不可能的。但是,您可以将调用拆分成类似的东西(根据lazy1的建议,你已经摆脱了大量的高管):
changeProject
通过这种方式而不是无用地尝试“连接到无”,您将看到所有名称在您的错误日志中导致令人惊讶的返回值,然后可以根据该信息继续调试。但是,更有可能的是,通过查看connect
的来源,您的错误实际上可能变得明显。
修改:changeProject
的参数当然来自connect
(而不是来自其他{{1}}! - ) - 相应地修复了代码段。< / p>
答案 2 :(得分:0)
我认为你运行'exec'太多了,IMO。您的问题是您正在尝试连接到QPushButton的.clicked(),这实际上是一个信号。你真的需要在这里传递论点吗?
exec 'self.btn_%s.clicked.connect(self.changeProject("%s"))' % (x, x)
因为如果不这样做,你可以这样连接:
self.connect(self.btn_%s, SIGNAL('clicked()'), self.changeProject)
如果您需要知道单击了哪个按钮,可以遍历列表以查找单击的按钮:
for x in buttons:
if x.isDown(): (function)
您也可以使用pyqtSignal。
答案 3 :(得分:0)
感谢您的帮助。我偶然发现了QSignalMapper,结果证明这正是我所需要的。
http://pysnippet.blogspot.com/2010/06/qsignalmapper-at-your-service.html
答案 4 :(得分:0)
QSignalMapper是使用Qt实现这一目标的可接受方式,但我发现PyQt有点麻烦,因为有一些更简单的选项可用。最简单的可能是1)用唯一的id标记每个按钮,这样你就可以区分它们(或者只是使用按钮的文本),然后2)使用QObject.sender()来确定发出信号的按钮。例如:
for x in self.buttons:
name = str(x)
button = QtGui.QPushButton(Frame)
button.setText(name)
button.uniqueId = name ## make this whatever you want..
button.clicked.connect(buttonClicked)
def buttonClicked():
button = QObject.sender()
uid = button.uniqueId ## got your ID back
答案 5 :(得分:0)
我想暗示这一点,并提到我刚刚用来解决这个策略的另一个策略/黑客。这是一个有点特定的策略并不总是有效,但我选择为更近期的这种设置实现的操作是将按钮设置为可检查。
由于我当时能够遍历布局并简单地检查哪个按钮为.isChecked(),因此最终阻力最小。无需SignalMapping或额外属性。