我想创建一个按钮循环,并在按下它们时执行命令。
k=0
for row in list:
delete_list.append("button_delete"+str(k))
delete_list[k] = Gtk.Button(label="Delete")
grid.attach(delete_list[k], columns+1, k, 1, 1)
delete_list[k].connect("clicked",globals()["on_button"+str(k)+"_clicked"])
k+=1
按钮显示正确,但我无法连接"点击"信号。
delete_list[k].connect("clicked",globals()["on_button"+str(k)+"_clicked"])
KeyError: 'on_button0_clicked'
我首先认为错误是因为on_button0_clicked没有方法,但我创建它并且我仍然得到同样的错误。
另外,如果有一些好的方法/建议来动态创建按钮响应的方法,那就太好了。我实际上需要为使用" k"的每个按钮创建一个方法。计数器。
答案 0 :(得分:2)
要动态创建一个将循环变量绑定为本地变量的函数,您需要一个工厂函数来生成它们:
def callback_factory(num):
def new_callback(widget):
print(widget, num)
return new_callback
for k, row in enumerate(somelist):
button = Gtk.Button(label=str(k))
button.connect('clicked', callback_factory(k))
这避免了一个常见的陷阱,即在循环体内创建方法或lambda导致为每个按钮单击打印相同的东西。这是由于环境函数创建时绑定到生成的函数,其中k变量在所有回调之间变异和共享。使用下面的代码可以观察到陷阱,这些代码无法正常工作:
for k, row in enumerate(somelist):
def callback(widget):
print(k)
button = Gtk.Button(label=str(k))
button.connect('clicked', callback)
PyGObject还支持传递给回调的唯一用户数据per-connect调用:
def callback(widget, num):
print(widget, num)
for k, row in enumerate(somelist):
button = Gtk.Button(label=str(k))
button.connect('clicked', callback, k))
这允许使用具有变化参数的相同回调,在某些情况下可以更清晰。
旁注:掩盖内置"列表"可能不是一个好主意。通过将它分配给您自己的列表实例来进行分类。