Python GUI programming using drag and drop, also incorporating stdout redirect

27,285

Solution 1

If you want to use Tkinter:

from Tkinter import *
import tkFileDialog 


class Redir(object):
    # This is what we're using for the redirect, it needs a text box
    def __init__(self, textbox):
        self.textbox = textbox
        self.textbox.config(state=NORMAL)
        self.fileno = sys.stdout.fileno

    def write(self, message):
        # When you set this up as redirect it needs a write method as the
        # stdin/out will be looking to write to somewhere!
        self.textbox.insert(END, str(message))

def askopenfilename():
    """ Prints the selected files name """
    # get filename, this is the bit that opens up the dialog box this will
    # return a string of the file name you have clicked on.
    filename = tkFileDialog.askopenfilename()
    if filename:
        # Will print the file name to the text box
        print filename


if __name__ == '__main__':

    # Make the root window
    root = Tk()

    # Make a button to get the file name
    # The method the button executes is the askopenfilename from above
    # You don't use askopenfilename() because you only want to bind the button
    # to the function, then the button calls the function.
    button = Button(root, text='GetFileName', command=askopenfilename)
    # this puts the button at the top in the middle
    button.grid(row=1, column=1)

    # Make a scroll bar so we can follow the text if it goes off a single box
    scrollbar = Scrollbar(root, orient=VERTICAL)
    # This puts the scrollbar on the right handside
    scrollbar.grid(row=2, column=3, sticky=N+S+E)

    # Make a text box to hold the text
    textbox = Text(root,font=("Helvetica",8),state=DISABLED, yscrollcommand=scrollbar.set, wrap=WORD)
    # This puts the text box on the left hand side
    textbox.grid(row=2, column=0, columnspan=3, sticky=N+S+W+E)

    # Configure the scroll bar to stroll with the text box!
    scrollbar.config(command=textbox.yview)

    #Set up the redirect 
    stdre = Redir(textbox)
    # Redirect stdout, stdout is where the standard messages are ouput
    sys.stdout = stdre
    # Redirect stderr, stderr is where the errors are printed too!
    sys.stderr = stdre
    # Print hello so we can see the redirect is working!
    print "hello"
    # Start the application mainloop
    root.mainloop()

What this does is creates a window with a button and a text box, with stdout redirect.

Currently in Tkinter you can't drag and drop files on to the open tk window(you can if you use tkdnd), so I have included a different way of getting the path of a file.

The way I have included to select a file is the askopenfilename dialog from tkFileDialog, this opens up a file browser and the path file selected is returned as a string.

If you have any questions or this doesn't quite do what your looking for please leave a comment!

Solution 2

Have a look at GTK. It is a really powerful library. Not the simplest, that's a fact, but once you get to understand how things work, it becomes much easier. Here's the official tutorial

If oyu are still using Python2, I think you should use PyGTK but it has been replaced by gl (which is described in the above tutorial). A good tutorial for PyGTK can be found here.

For a static interface, you can use glade which produces XML files that are then read by GTKBuilder to create the "real" interface. The first tutorial that I've found is available here

Share:
27,285
Clinton Moffat
Author by

Clinton Moffat

Updated on December 24, 2020

Comments

  • Clinton Moffat
    Clinton Moffat over 3 years

    I'm new to programming & new to python. I've just developed my first script, it prosesses file, but at the moment only from the commandline.

    This is just a hobby to me so my job does not depend on it :-)

    I've spent a few days now trying to get my head around python gui development & have come to the conclusion that I must be stupid.

    I've looked at wxpython & Tkinter & do not understand either, although Tkinter seems to be the easier out of the two. I've even looked at wysiwyg tools like Boa Contrictor & wxglade. I do not even understand how to use those. I would prefer to just stick with my editor & code manually anyway.

    My problem is this:

    I would like to create a desktop window with either 1 or two objects, depending on what works best. If just one object then a text box of some sort, if 2 objects then a text box & an image.

    I want to be able to drag file from a file manager & drop them on my script window, this is just to pass the filenames to my script.

    I than want to redirect stdout to an object within my desktop window so that all script output appears within the desktop window.

    I'm not sure if one object can do both things or not. If it can than just a text box would suffice, else drop files onto image & have redirected output going to the text box.

    I have found drag & drop examples on the web but nothing which incorporates stdout redirect, & I've not been able to successfully modify any of the examples that I've come across.

    If somee kind sole has the time to demonstrate how to achieve what I want & explain how its works I would greatfully appreciate it!

    ----EDIT ----

    I've been playing around with 2 examples & have managed to hash the 2 together in order to get what I wanted working. Code is below. It's not cleaned up yet ( old comments etc... ), but it works.

    #!/usr/bin/python
    
    # The next two lines are not necessary if you installed TkDnd
    # in a proper place.
    
    import os
    from Tkinter import *
    os.environ['TKDND_LIBRARY'] = '/home/clinton/Python/tkdnd2.6/'
    
    import Tkinter
    from untested_tkdnd_wrapper import TkDND
    
    
    class Redir(object):
        # This is what we're using for the redirect, it needs a text box
        def __init__(self, textbox):
            self.textbox = textbox
            self.textbox.config(state=NORMAL)
            self.fileno = sys.stdout.fileno
    
        def write(self, message):
            # When you set this up as redirect it needs a write method as the
            # stdin/out will be looking to write to somewhere!
            self.textbox.insert(END, str(message))
    
    root = Tkinter.Tk()
    
    dnd = TkDND(root)
    
    textbox = Tkinter.Text()
    textbox.pack()
    
    def handle(event):
        event.widget.insert(END, event.data)
        content = textbox.get("0.0",Tkinter.END)
        filename = content.split()
    
    dnd.bindtarget(textbox, handle, 'text/uri-list')
    
    #Set up the redirect 
    stdre = Redir(textbox)
    # Redirect stdout, stdout is where the standard messages are ouput
    sys.stdout = stdre
    # Redirect stderr, stderr is where the errors are printed too!
    sys.stderr = stdre
    # Print hello so we can see the redirect is working!
    print "hello"
    # Start the application mainloop
    root.mainloop()
    

    Examples are: python drag and drop explorer files to tkinter entry widget

    And also the example provided kindly by Noelkd.

    In order for this code to work you must create the wrapper from first example. Also currently code just displays dragged file in window, however variable is in place to be passed onto the script which runs behind the gui interface.