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.