【问题标题】:PyGObject, Looping buttonsPyGObject,循环按钮
【发布时间】:2014-06-28 18:39:31
【问题描述】:

我想创建一个按钮循环,并在按下它们时执行命令。

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”计数器的按钮创建一个方法。

【问题讨论】:

  • “我首先认为错误是因为没有 on_button0_clicked 方法,但我创建了它,但仍然遇到同样的错误。” - 是某个类的方法而不是全局范围?
  • 是的,该方法在同一个类中,将它放在全局范围内可以修复错误:)

标签: python-2.7 pygobject


【解决方案1】:

要动态创建将循环变量绑定为局部变量的函数,您需要一个工厂函数来生成它们:

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 还支持传递给回调的每个连接调用的唯一用户数据:

def callback(widget, num):
    print(widget, num)

for k, row in enumerate(somelist):
    button = Gtk.Button(label=str(k))
    button.connect('clicked', callback, k))

这允许使用带有不同参数的相同回调,这在某些情况下可以更简洁。

旁注:通过将内置“列表”类分配给您自己的列表实例来掩盖它可能不是一个好主意。

【讨论】:

  • 说实话,我有点迷失了你的一些 cmets,我仍然需要阅读有关 python 和 PyGobject 的信息。 (我刚开始学习编程)。第一个解决方案效果很好,这就是我正在使用的。第二个总是打印 67,最后一个对我来说有点奇怪,因为 button.connect('clicked', k)) 从不调用回调函数。无论如何,第一个解决方案效果很好,我会尽力理解你所说的一切,看起来很有趣
  • 不用担心,中间的示例应该演示一个您可能希望工作但没有工作的问题案例。最后一个示例缺少我修复的回调参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
  • 2016-03-20
  • 2018-06-25
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多