Part of my research requires doing analysis on graphical programs. These are all Python programs using Tkinter. I needed to see whether a program would behave differently given different inputs. Here, the inputs include keypresses, mouse clicks and so on. The problem was that I got thousands of programs to analyze and it was impossible for me to give inputs one by one, so I needed to write code to do this.

There are already some good websites that have pretty good documentation on Tkinter, but I couldn't find a site mentioning automatically generating events. Fortunately, some people on stackoverflow gave their solutions. I followed their suggestions and here's what I've got.

First, I used two threads to do this. One for running my Tkinter program and another for generating the events. Here's the code for the thread generating events:

import threading;

class EventGenerator(threading.Thread):
    def __init__(self, target_widget):
        threading.Thread.__init__(self);

        # Here is the widget that accepts events
        self.target = target_widget;

    def run(self):
        # I make the program pause here,
        # because I want the GUI program to run first
        import time;
        time.sleep(0.2);

        # The GUI program needs to get focus first, or it won't
        # catch any events
        self.target.focus_force();

        # Now we can generate any event we want

        # keypress
        self.target.event_generate("<KeyPress-Up>");

        # mouse click
        self.target.event_generate("<Button-1>", x = 100, y = 100);

        # finally, we update the widget
        self.target.update();

Since we are using two threads, we need a driver program that runs the Tkinter program and the event generating thread.

if __name__ == '__main__':
    if(len(sys.argv) < 2):
        sys.exit("Usage: %s [Tkinter program filename]" % sys.argv[0]);

    # Here you define your Tkinter app
    gui_prog = App();

    # my_widget is a widget that accepts events
    egen = EventGenerator(app.my_widget);

    # now we start the event generator and the TKinter program
    egen.start();
    gui_prog.mainloop();