由于python是我的第一个OO语言,我无法理解。 我需要运行一个对话框,并将返回值放入从另一个函数传递的变量中。 在dGetPath中,如何绕过变量变量?
def dGetPath(self, widget, data=None):
print "%s needs to be filled with output from a dialog here" % (data)
def dupChk(self, widget, data=None):
print "if I figure out dGetPath... %s should be easy" % (data)
def __init__(self):
self.mainwin = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.mainwin.set_position(gtk.WIN_POS_CENTER)
# ...
self.Apath = gtk.Button("A in path")
self.Apath.connect("clicked", self.dGetPath, "Apath")
self.Aopath = gtk.Button("A out path")
self.Aopath.connect("clicked", self.dGetPath, "Aopath")
self.dupchkA = gtk.Button("Dupe check A") # check A path for duplicates
self.dupchkA.connect("clicked", self.dupChk, "dupchkA")
self.dupchkA.set_tooltip_text("check A path for duplicates using MD5 sum")
self.Bpath = gtk.Button("B in path")
self.Bpath.connect("clicked", self.dGetPath, "Bpath")
self.Bopath = gtk.Button("B out path")
self.Bopath.connect("clicked", self.dGetPath, "Bopath")
self.dupchkB = gtk.Button("Dupe check B") # check B path for duplicates
self.dupchkB.connect("clicked", self.dupChk, "dupchkB")
self.dupchkA.set_tooltip_text("check B path for duplicates using MD5 sum")
# ...
答案 0 :(得分:2)
如果我正确地阅读了您的问题,您会对event handling和callback functions感到困惑 - 您需要对值进行某事(dupChk()
)当用户点击Apath
时,从对话框(尚未定义...)返回。
我认为你在这里缺少的是存放filechooser(self.APath
?)所选文件或目录的地方 - 以及产生的必要性单击按钮时的filechooser对话框。
但是你的Apath
按钮还不知道路径,所以你不能给它一个在路径上工作的回调函数。你可以:
给回调一个函数,为你的filechooser打开一个对话框,然后在结果上调用dupChk()
函数。
通过其他机制提供filechooser(窗口中嵌入的另一个按钮?总是打开?适合打字的文本字段?)并重新标记Apath
按钮“Check A for重复”。 filechooser回调存储到self.Apath
,按钮回调调用dupChk(self.Apath)
。
<强>更新强>
同时学习GUI编程和 OO编程可能是一个重大障碍,但GUI小部件的类层次结构非常适合面向对象的设计,这个项目看起来很平易近人从一开始的大小,在那里做得很好。
面向对象编程只是将自定义类型与这些类型上的操作捆绑在一起的一种方法。您可以创建一个Window
对象来存储与窗口和相关的属性,这些属性适用于特定的Window
对象。或者您创建一个Widget
对象,提供所有图形小部件共有的数据 - X位置,Y位置,宽度,高度,小部件是否可以在X或Y维度上增长或缩小,可见或不可见等,和所有小部件共有的操作 - 设置X或Y位置,宽度,高度,增长和缩小控件,可见或不可见,然后,每个新的图形元素都从Widget
基本功能继承,然后可以提供特定于正在制作的新类型小部件的新数据或操作。
为了使单个图形控件保持简单,大多数GUI编程工具包都提供事件,每个图形元素都可以生成或使用它们。您提供回调 - 事件发生时调用的函数。大多数GUI编程环境的工作方式与“通常”编程非常不同;差异有时被称为inversion of control。从本质上讲,GUI工具包会设置所有内容,然后调用您提供的功能。 (您的main()
或者__init__()
函数只设置所有小部件和回调,然后启动等待事件的event loop,然后调用您的回调函数。)
回调机制允许您为不同位置的不同任务重用相同的窗口小部件类,具体取决于您安装的回调。此处Button
可能会退出该应用程序,另一个Button
可能会启动导弹或启动网络浏览器。
与Java不同,在Python中,并非所有都需要在一个类中完成。如果你的程序的顶级不值得上课,你不必把它放在一个类中。你可能想要将它全部放在一个类中,所以它更容易嵌入到未来的程序中,但是如果这个程序只需要解决一个小任务并且不太可能被嵌入,那就没有了需要过度复杂的编程任务。考虑到这一点,我写了一个小(并不是特别漂亮)的小型演示工具,显示如何显示两个FileChooserButtons
,如何连接到他们的"file-set"
信号,如何从有问题的文件选择器中获取文件名,和如何将文件选择器的结果存储到您选择的变量中。
我认为这是你最麻烦的最后一部分 - 如果这是C,你只需连接你的回调:
char *filea, *fileb;
hyptothetical_widget widget = new_hypothetical_widget("foo");
hypthetical_connect(widget, &callback, &filea);
并且&filea
(或&fileb
)足以选择您想要更新的指针。
Python使这有点棘手 - 没有办法只添加&
来传递指针。您可以做的是pass an array and modify the array in the callback。
我编写的这个小演示使用了这个“通过引用传递”技巧,可以很容易地使用相同的回调函数写入两个不同的变量,具体取决于它连接到哪个小部件:< / p>
#!/usr/bin/python
import gtk
def pick_file(widget, filename):
filename[0] = widget.get_filename()
print filename
update_entry_boxes()
def update_entry_boxes():
ea.set_text(filea[0])
eb.set_text(fileb[0])
filea=["None Selected"]
fileb=["None Selected"]
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
box = gtk.HBox();
ba = gtk.FileChooserButton("File A")
ba.connect("file-set", pick_file, filea)
bb = gtk.FileChooserButton("File B")
bb.connect("file-set", pick_file, fileb)
ea = gtk.Entry()
eb = gtk.Entry()
box.add(ba)
box.add(ea)
box.add(bb)
box.add(eb)
update_entry_boxes()
win.add(box)
win.show_all()
gtk.main()
我希望这有用。