LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 10-13-2012, 01:37 PM   #1
donnied
Member
 
Registered: Oct 2006
Distribution: Debian x64
Posts: 198

Rep: Reputation: 30
How to: tkinter-python to monitor a file, add buttons automatically, and exit cleanly


I had difficulties creating a program that used tkinter and python that allowed a file to be monitored, buttons to be added, and the program to be exited cleanly.

This arose in part from an awkward series of root.mainloop() and Tkinter.Tk() instances that were being generated and could not be exited cleanly even with the following code that should have ended it (this code is overkill – sys.exit alone should kill the program) –if you’re looking to kill Tkinter much of this will do it:
Code:
    def stop():
            global win
            win.quit()
            try:
                    del(win)
            except:
                    pass
            raise SystemExit
            sys.exit()
            return False
See posts such as this:
http://stackoverflow.com/questions/5...-quit-properly

If you’re trying to run processes concurrently with tkinter and it won’t close – the structure is most likely wrong. GTK had tolerated an abuse of the structure – allowing multiple main windows to be generated – tkinter won’t. Though I had originally used threading, most likely improperly as well, this comes with several dangers and wasn’t working and wasn’t necessary for what I was trying to do. The after method allowed the tkinter window and file checking to run seemingly simultaneously.

This post is very helpful in understanding / using `after`:
http://stackoverflow.com/questions/4...ers-event-loop

Basically, for a program to keep checking a file for changes and to reflect those changes in a list of buttons – the normal root = Tkinter.Tk() and root.main() format must be followed within the body. The looping and while statements are accomplished using “after”.

Basically, I used one function that completed once to construct the initial buttons (and they’re placed at the top as new buttons are added below) – makethelistofbuttons(), then each cycle runs refresh() which only adds new buttons.

[In gtk, I had originally attempted (with semi-success) to generate and destroy the list of buttons with each iteration of refresh(). That did not work here.]

The code necessary to create the file checking (seemingly concurrent) to running the tkinter window:
Code:
    bobsyouruncle = False
    
    def dothis():
            global bobsyouruncle
            try:
                    if bobsyouruncle == False:
                            bobsyouruncle = True
                            makethelistofbuttons()
                    else:
                            refresh()
            except:
                    pass
            win.after(2000,dothis)
    
    win.after(2000, dothis)
    win.mainloop()
Note – win.after is included in dothis() and within the main program.

To show how the buttons are read in and generated the complete code is provided below. It may also be worth mentioning that some people have warned against `win.update()` – but it seemed to be integral to getting the program to work.

Code:
    import Tkinter
    from Tkinter import *
    import sys
    import time
    
    
    win = Tkinter.Tk()
    
    somefilefile = open("users.txt", 'r')
   listofusers = []
    
    
    def findadditions(line):
            line = line.replace('"', '').strip()
            linelist = line.split()
            username = linelist[1]
            userstatus = checkforuser(username)
            if not userstatus:
                    global listofusers
                    global win
                    listofusers.append(username)
                    newbuttonname = username
                    newbuttonname = Tkinter.Button(win, text = username, command = lambda name=username:click_one(name))
                    newbuttonname.pack()
                    win.update()
    
    def checkforuser(username):
            return username in listofusers
    
    def click_one(newbuttonname):
	print newbuttonname, “was clicked”
    
    
    def refresh():
            global win
            somefilefile = open("users.txt", 'r')
            for line in somefilefile:
                    findadditions(line)
            somefilefile.close()
            win.update()
    
    def stop():
            global win
            win.quit()
            try:
                    del(win)
            except: 
                    pass
            raise SystemExit
            sys.exit()
            return False
    
    def makethelistofbuttons():
            global win
            global listofusers
            try:
                    somefilefile.close()
            except:
                    pass
            stopbutton = Tkinter.Button(win, text="Quit", command=lambda win=win:stop()).pack()
            refreshbutton = Tkinter.Button(win, text = "refresh", command = refresh).pack()
            somefilefile = open("somefile.nlist", 'r')
            for line in somefilefile:
                    findadditions(line)
            somefilefile.close()
            win.update()
    
    
    
    bobsyouruncle = False
    
    def dothis():
            global bobsyouruncle
            try:             
                    if bobsyouruncle == False:
                            bobsyouruncle = True
                            makethelistofbuttons()
                    else:
                            refresh()
            except:
                    pass
            win.after(2000,dothis)
    
    win.after(2000, dothis)
    win.mainloop()
    
    try:
            writethisdown.close()
    except: 
            pass
    
    raise SystemExit
    sys.exit()
 
  


Reply

Tags
exit, python, tkinter


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Tkinter - why no space between buttons? raskol Programming 1 04-06-2008 04:57 PM
k3b: cdrecord did not exit cleanly Joe Soap Linux - Newbie 1 01-07-2006 12:16 PM
How to cleanly exit 'man' - Changing File Properties rickh Linux - Newbie 4 04-21-2005 12:08 AM
Problem with k3b again, now cdrdao didn't exit cleanly krussell Linux - Software 3 02-08-2004 08:16 PM
Python: Tkinter. Chu Programming 0 11-10-2003 01:56 AM


All times are GMT -5. The time now is 05:39 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration