1

As python is my first OO language, I cannot understand. I need to run a dialog, and put the return into a variable passed from another function. How do I get around variable variables in this case, in 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")
    # ...
Joe Daddy
  • 13
  • 5
  • "How do I get around variable variables?" Kind of defeats the purpose of them being variables right? – Jesus Ramos Oct 25 '11 at 00:37
  • 1
    Can you describe what you mean by "variable variable"? Is that perhaps related to the [PHP terminology](http://php.net/manual/en/language.variables.variable.php)? – Greg Hewgill Oct 25 '11 at 00:38
  • I'm not sure, but it sounds like you might be wanting to pass variables by reference - see [this question](http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference) for information on that. – James Oct 25 '11 at 01:03
  • @GregHewgill: yes, exactly like the PHP terminology. – Joe Daddy Oct 25 '11 at 02:49

1 Answers1

2

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 on Apath.

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 into self.Apath, and the button callback calls dupChk(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 specific Window object. Or you create a Widget 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 the Widget 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 another Button 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:

char *filea, *fileb;
hyptothetical_widget widget = new_hypothetical_widget("foo");
hypthetical_connect(widget, &callback, &filea);

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:

#!/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()

I hope this is helpful.

Community
  • 1
  • 1
sarnold
  • 102,305
  • 22
  • 181
  • 238
  • After looking at the links you provided, you have a firm grasp on what I am looking for... I just don't understand how to code them properly. I think that if I solve the "Apath" portion first, I can solve the dupChk... If you could provide a link to a python tutorial that gives several examples geared toward a first-time learner, I would appreciate it. Everything I have found is terse and for people that already know OOP. – Joe Daddy Oct 25 '11 at 02:52
  • As I have been a shell script writer for some time (and made my own ASCII GUI's), learning the GUI part isn't so intense... As long as people are kind and explanatory (like your answer) to those without prior "type" knowledge (like myself), I expect it to go rather smoothly. BTW: thanks for the C, I am learning that as well in the background (the differences in procedural languages seem to be largely semantics). – Joe Daddy Oct 26 '11 at 05:20
  • Oh, cool; you've already got a good design aesthetic then. :) I'd like to suggest [Seven Languages in Seven Weeks](http://pragprog.com/book/btlang/seven-languages-in-seven-weeks) for a good fast-paced walkthrough of seven languages. Only Ruby is a 'pure' object oriented language out of the survey, but Scala is a nice 'bridge' between OO and Functional programming, and getting a good wide survey of how typing works in many languages is incredibly useful. For C, there's no better starting point than [The C Programming Language](http://en.wikipedia.org/wiki/The_C_Programming_Language). Have fun! – sarnold Oct 26 '11 at 22:36