gpt4 book ai didi

python : How can two GTK widgets interact with each other?

转载 作者:太空宇宙 更新时间:2023-11-04 10:44:50 25 4
gpt4 key购买 nike

在不实际点击按钮的情况下与按钮交互的正确方法是什么?

我有一个按钮“按钮”,点击后可以:

  • 调用方法“the_method”,打印传递给它的参数(此处为“文件名”)
  • 切换它自己的属性,这里是它的图标。

我有一个 TreeView ,其行必须在双击时:

  • 调用方法“the_method”,打印传递给它的参数(此处为“文件名”)
  • 切换“按钮”的属性,这里是它的图标。

只有第一部分有效。 “foo”函数被调用(通过按钮的回调,直接用于 TreeView 项)并且参数(“文件名”)被检索正常,但是如何执行作业的第 2 部分(更改“按钮”的属性, 这是它的图标)?


import gtk

class Lister(object):

def __init__(self):
self.hbox = gtk.HBox()

liststore = gtk.ListStore(str)
liststore.append(["foo"])
liststore.append(["bar"])
treeview = gtk.TreeView(liststore)
self.hbox.pack_start(treeview, False)
cell = gtk.CellRendererText()
col = gtk.TreeViewColumn("Column 1")
col.pack_start(cell, True)
col.set_attributes(cell,text=0)
treeview.connect('row-activated', self.open_file)
treeview.append_column(col)

def open_file(self, button, *args):
Buttons().the_method(self, "foo")

class Buttons(object):

OPEN_IMAGE = gtk.image_new_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
CLOSED_IMAGE = gtk.image_new_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_BUTTON)

def __init__(self):

self.button = gtk.Button() # THIS is the button to modify
self.hbox = gtk.HBox()
self.hbox.pack_start(self.button, False)
self.button.set_image(self.OPEN_IMAGE)

self.button.connect('clicked', self.the_method, "plop")
self.toggled = True

def the_method(self, button, filename):
print filename
print vars(self)

if self.toggled:
self.button.set_image(self.CLOSED_IMAGE)
self.toggled = False
else:
self.button.set_image(self.OPEN_IMAGE)
self.toggled = True

class GUI(object):

def delete_event(self, widget, event, data=None):
gtk.main_quit()
return False

def __init__(self):
self.window = gtk.Window()
self.window.set_size_request(100, 150)
self.window.connect("delete_event", self.delete_event)

vbox = gtk.VBox()
vbox.pack_start(Buttons().hbox, False, False, 1)
vbox.pack_start(Lister().hbox)

self.window.add(vbox)
self.window.show_all()
return

def main():
gtk.main()

if __name__ == "__main__":
GUI()
main()

最佳答案

我强烈反对 user1146332 的回答。这不是 GTK+ 问题,也不是强设计问题,只是面向对象编程问题。错误的原因是您这样调用 the_method:

Buttons().the_method(self, "foo")

这是行不通的,因为您混淆了两个不同的基本事物:一个类和一个类的实例。当您调用 Buttons() 时,您正在创建 Buttons 类的新实例。因此,由于此类不是单例,您实际上是在创建一个新实例,带有一个新的 GtkButton,并且最终不会与您之前创建的按钮进行交互。

这里的解决方案是让 Lister 对象知道它需要修改什么,这意味着围绕您之前创建的 Buttons 实例进行存储,例如在 self.button,并在其上调用 the_method

self.button.the_method("foo")

这是您的代码的略微修改版本。重要的是 Lister 实例现在知道它需要修改的 Buttons 实例。

import gtk

class Lister(object):

def __init__(self, button):
self.hbox = gtk.HBox()
self.button = button

liststore = gtk.ListStore(str)
liststore.append(["foo"])
liststore.append(["bar"])
treeview = gtk.TreeView(liststore)
self.hbox.pack_start(treeview, False)
cell = gtk.CellRendererText()
col = gtk.TreeViewColumn("Column 1")
col.pack_start(cell, True)
col.set_attributes(cell,text=0)
treeview.connect('row-activated', self.open_file)
treeview.append_column(col)

def open_file(self, button, *args):
self.button.the_method("foo")

class Buttons(object):

OPEN_IMAGE = gtk.image_new_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
CLOSED_IMAGE = gtk.image_new_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_BUTTON)

def __init__(self):

self.button = gtk.Button() # THIS is the button to modify
self.hbox = gtk.HBox()
self.hbox.pack_start(self.button, False)
self.button.set_image(self.OPEN_IMAGE)

self.button.connect('clicked', self.the_method, "plop")
self.toggled = True

def the_method(self, filename):
print filename
print vars(self)

if self.toggled:
self.button.set_image(self.CLOSED_IMAGE)
self.toggled = False
else:
self.button.set_image(self.OPEN_IMAGE)
self.toggled = True

class GUI(object):

def delete_event(self, widget, event, data=None):
gtk.main_quit()
return False

def __init__(self):
self.window = gtk.Window()
self.window.set_size_request(100, 150)
self.window.connect("delete_event", self.delete_event)

vbox = gtk.VBox()
buttons = Buttons()
vbox.pack_start(buttons.hbox, False, False, 1)
vbox.pack_start(Lister(buttons).hbox)

self.window.add(vbox)
self.window.show_all()
return

def main():
gtk.main()

if __name__ == "__main__":
GUI()
main()

但是,仍有很大的改进空间。我建议您不要使用 __init__ 函数来创建您的小部件,而是使用 create 方法来返回您的小部件树的顶层小部件。这是因为您不能在 __init__ 中返回任何内容,因此使用不同的方法比在那里引发异常更容易。

b = Buttons()
vbox.pack_start(b.create(), False, False, 1)
l = Lister(b)
vbox.pack_start(l.create(), False, False, 1)

其他改进可能是(抱歉,我在这里为 GTK 类/函数使用 C 命名,我比 python 更了解它):

  • 使用 GtkToggleButton 而不是自己跟踪按钮状态
  • 使用 gtk_button_set_use_stock 告诉按钮将您将在按钮中设置的标签解释为按钮的股票 ID(这也可能打印相关文本,对此不确定)
  • 切换到 GTK 3(使用 pyGObject),因为这是 GTK 2 代码(使用 pyGTK),除非你想要 Windows 兼容性

linuxfr 见:-)

关于 python : How can two GTK widgets interact with each other?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18151670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com