python:如何绕过可变变量
由于 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")
# ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果我正确地阅读了您的问题,您对 事件处理 感到困惑回调函数 - 你需要做一些事情 (
dupChk()
) 当用户单击Apath
时从对话框(尚未定义...)返回的值。我认为您在这里缺少的是存储由 文件选择器 (
self.APath
?) - 并且需要在单击按钮时生成文件选择器对话框。但是您的
Apath
按钮尚不知道路径,因此您无法为其提供在路径上工作的回调函数。您可以:提供一个为文件选择器打开对话框的函数作为回调,然后对结果调用
dupChk()
函数。通过其他机制可以使用文件选择器(另一个按钮?嵌入在始终打开的窗口中?适合仅键入的文本字段?)并重新标记您的
Apath
按钮“检查 A重复”。文件选择器回调存储到 self.Apath 中,按钮回调调用 dupChk(self.Apath) 。更新
同时学习 GUI 编程和面向对象编程可能是一个重大障碍,但是 GUI 小部件的类层次结构非常适合面向对象的设计,并且这项目的规模似乎是可以开始的,所以做得很好。
面向对象编程只是一种将定制类型与这些类型上的操作捆绑在一起的方法。您创建一个
Window
对象来存储与窗口相关的属性以及作用于特定Window
对象的方法。或者您创建一个Widget
对象,该对象提供所有图形小部件通用的数据 - X 位置、Y 位置、宽度、高度、小部件是否可以在 X 方向上增大或缩小或 Y 尺寸,可见或不可见等,和所有小部件通用的操作 - 设置 X 或 Y 位置、宽度、高度、增大和缩小控件、可见或不可见等。然后每个新的图形元素继承Widget
的基本功能,然后可以提供特定于正在制作的新型小部件的新数据或操作。为了保持各个图形控件的简单性,大多数 GUI 编程工具包都提供每个图形元素都可以生成或使用的事件。您提供回调——事件发生时调用的函数。大多数 GUI 编程环境的工作方式与“通常”编程有很大不同;这种差异有时称为控制反转。本质上,GUI 工具包会设置所有内容,然后调用您提供的函数。 (您的
main()
或在本例中为__init__()
函数只是设置所有小部件和回调,然后启动 事件循环等待事件然后调用您的回调函数。)回调机制允许您为不同的任务重复使用相同的小部件类不同的地方,取决于你的回调 安装。这里的一个
Button
可能会退出应用程序,而那里的另一个Button
可能会发射导弹或启动 Web 浏览器。与 Java 不同,在 Python 中,并非所有事情都需要在类中完成。如果您的程序的最高级别不值得进入班级,则不必将其放入班级。无论如何,您可能想要将所有内容都放在一个类中,这样就更容易嵌入到未来的程序中,但如果这个程序只需要解决一个小任务并且不太可能被嵌入,那么就没有需要使编程任务过于复杂。考虑到这一点,我编写了一个小(不是特别漂亮)的小演示工具,它展示了如何显示两个
FileChooserButtons
,如何连接到它们的“file-set”
信号,如何从相关文件选择器获取文件名,以及如何将文件选择器的结果存储到您选择的变量中。我认为这是您遇到最多麻烦的最后部分 - 如果这是 C,您只需像这样连接回调:
和
&filea
(或& fileb
)足以选择您想要更新的指针。Python 使这有点棘手——没有办法只添加
&
来传递指针。您可以做的是传递一个数组并在回调中修改数组。我编写的小演示使用这种“按引用传递”技巧,可以轻松使用相同的回调函数写入两个不同的变量,具体取决于它连接到的小部件:
我希望这是有帮助。
If I read your question correctly, you're confused about event handling and callback functions -- you need to do something (
dupChk()
) on the value returned from a dialog box (not yet defined...) when the user clicks onApath
.What I think you're missing here is some place to store the file or directory chosen by a filechooser (
self.APath
?) -- and the need to spawn a filechooser dialog box when a button is clicked.But your
Apath
button doesn't know the path yet, so you can't give it a callback function that works on a path. You could:give as callback a function that opens a dialog box for your filechooser and then calls the
dupChk()
function on the result.have the filechooser available through some other mechanism (another button? embedded in the window always-open? a text field suitable for just typing?) and re-label your
Apath
button "Check A for Duplicates". The filechooser callback stores intoself.Apath
, and the button callback callsdupChk(self.Apath)
.Update
Learning both GUI programming and OO-programming at once might be a significant hurdle, but the class hierarchies of GUI widgets is perfectly suited to an object-oriented design, and this project seems like an approachable size to start with, so good job there.
Object Oriented programming is simply a way to bundle custom-made types with actions on those types. You create a
Window
object to store attributes related to a window and the methods that work on a specificWindow
object. Or you create aWidget
object that provides data common to all the graphical widgets -- X position, Y position, width, height, whether the widget can grow or shrink in X or Y dimensions, visible or invisible, etc., and the operations common to all widgets -- setting X or Y position, width, height, grow and shrink controls, visible or invisible, etc. Then every new graphical element inherits from theWidget
the base functionality and can then provide new data or operations specific to the new type of widget being made.To keep the individual graphical controls simple, most GUI programming toolkits provide events that every graphical element can generator or consume. You provide callbacks -- functions that are called when the events occur. Most GUI programming environments work very differently than "usual" programming; the difference is sometimes called inversion of control. In essence, the GUI toolkit sets up everything and then calls functions that you provide. (Your
main()
or, in this case,__init__()
function just sets up all the widgets and callbacks and then starts an event loop that waits for events then calls your callback functions.)The callback mechanisms let you re-use the same widget classes for different tasks in different places, depending upon the callbacks you install. A
Button
here might quit the application, and anotherButton
there might launch the missiles or start a web browser.Unlike Java, in Python, not everything needs to be done inside a class. If the top level of your program doesn't deserve to be in a class, you don't have to put it in a class. You might want to put it all in a class anyway, so it is easier to embed into future programs, but if this program just needs to solve a small task and won't likely be embedded, there's no need to overly complicate the programming task. With this in mind, I've written a small (and not particularly pretty) little demonstration tool that shows to how display two
FileChooserButtons
, how to connect to their"file-set"
signal, how to get the filename from the filepicker in question, and how to store the results from the filepicker into a variable of your choosing.I think it is the last portion that you had the most trouble with -- if this were C, you'd just connect your callbacks like this:
and the
&filea
(or&fileb
) would suffice to select which pointer you wanted updated.Python makes this a little tricky -- there's no way to just add
&
to pass a pointer. What you can do is pass an array and modify the array in the callback.The little demo I wrote uses this "pass by reference" trick to make it easy to use the same callback function to write into two different variables, depending upon which widget it was connected to:
I hope this is helpful.