473,748 Members | 7,590 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

My Tkinter Threading nightmare

Hi all,

I don't really understand how to properly use threading in my programs,
however I have managed to get by so far using them improperly. Once
again I have come up to what I think is something that won't work
because of the way the program is set up.

I have a long running process running underneath a gui in a different
thread, and a progress bar that updates the status of the operation.
What I would like to do is use something like :

self.progressWi ndow.protocol(' WM_DELETE_WINDO W', self.callback)

and setup the callback to kill the operation and then the window when
the user clicks on the X of the progress window. I've implemented this
in my code, but clicking on the X does nothing until I kill the main
thread (i think), and then my callback is run. I've also had problems
in the past of the gui not refreshing properly, which leads me to
believe that both of these are thread related. Any help would be
immensely appreciated.

~Sean DiZazzo

~~~~~~~~~~~~~~~ ~~~~

import sys, os, time

libdir = "/usr/local/sw/lib"
sys.path.append (libdir)

import ProgressBarView , Folder, P

from Tkinter import *
from tkFileDialog import askopenfilename s
from tkMessageBox import showerror, showinfo
import pexpect, ssh_session

import P
import Pmw

rootWin = Tk()

class Window(Frame):
label = None
initialdir = "/"

dest = "/tmp"
folder = None
logpath = "/tmp/Send.log"
copyindex = 0
files = []
progressWindow = None
session = None
password = P.P()
ssh = ssh_session.ssh _session("root" , "XX.XX.XX.X X",
password.Decryp t(password.sean ))

timeout = 30

def __init__(self, parent=None):
Frame.__init__( self, parent)
rootWin.title(" Send to Blah")
rootWin.resizab le(width=0,heig ht=0)
self.pack()
self.progress_a nd_log()
f = Frame(self)
openfunc = (lambda self=self, name=None: self.openfolder ())
Button(f, text="Choose", command=openfun c).pack(side="l eft")
self.label = Label(f, text=' <--- Choose files', bg="grey", width=40,
justify='left', anchor='w')
self.label.pack (side="left", anchor='w', padx=5)
f.pack(padx=10, pady=10, side='left', fill='both', anchor='w')
submitfunc = (lambda self=self, name=None: self.submit())
b = Button(self, text="Send", command=submitf unc)
b.pack(side="ri ght", padx=5)
def openfolder(self ):
self.files = []
self.files_tupl e = askopenfilename s(parent=rootWi n, initialdir="/")

for file in self.files_tupl e:
self.files.appe nd(file)

self.files.sort ()

label = "Click button to send files -->"
self.st.configu re(text_state = 'normal')
self.st.clear()
self.st.insert( 'end', "Files to be copied:\n")
self.st.insert( 'end', "~~~~~~~~~~~~~~ ~~~~~\n")
for file in self.files:
self.st.insert( 'end', os.path.split(f ile)[-1] + "\n")
self.st.insert( 'end', " \n \n")
self.st.configu re(text_state = 'disabled')
self.label.conf ig(text='Click to send files --- ', justify='right' ,
anchor='e')

def callback(self):
"""Need to get the pid here and kill the running process"""

def submit(self):
files = self.files
dest = Folder.Folder(s elf.dest)

for file in files:
if self.ssh.exists (os.path.join(d est.path,
os.path.split(f ile)[-1])):
showerror("erro r", "The file '%s' already exists" %
os.path.join(de st.path, os.path.split(f ile)[-1]))
return 0

import threading
geometry = None

for file in files:
self.progressWi ndow = Toplevel(rootWi n)
self.progressWi ndow.protocol(' WM_DELETE_WINDO W', self.callback)
self.progressWi ndow.geometry(g eometry)
self.progressWi ndow.title("Pro gress")
self.progressWi ndow.resizable( width=0,height= 0)

self.proglabel = Label(self.prog ressWindow, text='Copying.. .',
anchor=NW, justify=LEFT, width=30)
self.proglabel. pack(fill=X, expand=1)
self.progressBa r =
ProgressBarView .ProgressBarVie w(self.progress Window)
self.progressBa r.pack(fill=X)

threading.Threa d(target=self.t hreadedCopy,arg s=(file, dest)).start()

#grab the location from the first window
if geometry is None:
self.progressBa r.updateProgres s(0)
geometry = self.progressWi ndow.geometry()

self.incrementP rogress(self.pr ogressWindow, file, dest)

self.label.conf ig(text=" <--- Choose files", justify='left',
anchor='w')
self.files=[]

def progress_and_lo g(self):
self.st = Pmw.ScrolledTex t(rootWin, borderframe = 1,
usehullsize = 1,
hull_width = 400,
hull_height = 150,
text_wrap='none ',
#text_font = fixedFont,
text_padx = 4,
text_pady = 4,
)
self.st.configu re(text_state = 'disabled')

self.st.pack(pa dx = 5, pady = 5, fill = 'both', expand = 1)
def threadedCopy(se lf, file, dest):
self.ssh.scp(fi le, os.path.join(de st.path, os.path.split(f ile)[1]))

def appendToLog(sel f, src, dest):
dest_size = self.ssh.size(d est.path)
try:
dest_size = float(dest_size )
except:
dest_size = 0

if src.size == dest_size:
status = "SUCCESS"
else:
status = "FAILED"
entry = "%s - %s %s, %s\n" % (time.ctime(tim e.time()), status,
src.name, src.readableSiz e)

f = open(self.logpa th, 'a')
f.write(entry)
f.close()

self.st.configu re(text_state = 'normal')
self.st.insert( 'end', entry)
self.st.configu re(text_state = 'disabled')
def incrementProgre ss(self, window, file, dest):
import File
src = File.File(file)
dest = File.File(os.pa th.join(dest.pa th, os.path.split(f ile)[-1]))
start = time.time()
p = 0
last_dest = 0
same_count = 0

while p < 100:
d_size = self.ssh.size(d est.path)
try:
float(d_size)
except:
"Couldn't turn %s into a float" % d_size
continue

if last_dest == d_size and same_count == 40:
showerror("erro r", "Error copying %s\nRemoving the partially
transferred file and continuing..." % dest.path)
self.ssh.ssh("s udo rm %s" % dest.path)

if d_size == None:
d_size = 1000

self.proglabel. config(text=src .name)

p = (float(d_size) / float(src.size) ) * 100.0

d_size = self.ssh.size(d est.path)
if last_dest == d_size:
same_count = same_count +1

print "P:", p
self.progressBa r.updateProgres s(p)
self.update_idl etasks()
time.sleep(0.25 )
last_dest = d_size

self.appendToLo g(src, dest)
window.destroy( )
return
if __name__ == "__main__":
Window().mainlo op()

Jan 25 '07 #1
5 4250
ha**********@gm ail.com writes:
and setup the callback to kill the operation and then the window when
the user clicks on the X of the progress window. I've implemented this
in my code, but clicking on the X does nothing until I kill the main
thread (i think), and then my callback is run. I've also had problems
in the past of the gui not refreshing properly, which leads me to
believe that both of these are thread related. Any help would be
immensely appreciated.
That was more code than I was willing to sit and read, but basically
the tkinter thread blocks unless there's tkinter events. The usual
trick for what you're trying to do is to set up a tk.after event to
run every 20 msec or so. That can check for commands on a queue to
launch operations, kill windows, or whatever. In your Window class
you'd have something like (this is pseudocode, I don't remember the
exact params and args off the top of my head so you'll have to check
them):

def __init__(self, ...):
...
self.after(20, self.idle)

def idle(self):
# read and execute any commands waiting on the queue
while True:
try:
func, args, kw = self.cmd_queue. get(block=False )
except QueueEmpty:
return
func (*args, **kw)

cmd_queue is a queue that you set up ahead of time, and you use it to
send commands into your gui thread from other threads, such as window
kill. Don't call gui functions directly as tkinter is not
thread-safe.
Jan 25 '07 #2
Paul Rubin <http://ph****@NOSPAM.i nvalidwrites:
def idle(self):
# read and execute any commands waiting on the queue
while True:
try:
func, args, kw = self.cmd_queue. get(block=False )
except QueueEmpty:
return
func (*args, **kw)
Whoops, I forgot, you have to set up the after event again at the end
of this:

def idle(self):
# read and execute any commands waiting on the queue
while True:
try:
func, args, kw = self.cmd_queue. get(block=False )
except QueueEmpty:
return
func (*args, **kw)
self.after(20, self.idle)
Jan 25 '07 #3

On Jan 24, 7:35 pm, Paul Rubin <http://phr...@NOSPAM.i nvalidwrote:
Paul Rubin <http://phr...@NOSPAM.i nvalidwrites:
def idle(self):
# read and execute any commands waiting on the queue
while True:
try:
func, args, kw = self.cmd_queue. get(block=False )
except QueueEmpty:
return
func (*args, **kw)Whoops, I forgot, you have to set up the after event again at the end
of this:

def idle(self):
# read and execute any commands waiting on the queue
while True:
try:
func, args, kw = self.cmd_queue. get(block=False )
except QueueEmpty:
return
func (*args, **kw)
self.after(20, self.idle)
Thanks Paul. That has made more sense than all of my scrounging
combined, but I still need to mess around with the idea and code some.
How can I put something like the window delete into the command queue?
Isn't window.protocol () just binding the close window button to a
function?

I'll look deeper and experiment and try to make sense of it once again
tomorrow. :)

~Sean

Jan 25 '07 #4
ha**********@gm ail.com writes:
try:
func, args, kw = self.cmd_queue. get(block=False )
except QueueEmpty:
return
func (*args, **kw)
>
Thanks Paul. That has made more sense than all of my scrounging
combined, but I still need to mess around with the idea and code some.
How can I put something like the window delete into the command queue?
Isn't window.protocol () just binding the close window button to a
function?
self.progressWi ndow.protocol(' WM_DELETE_WINDO W', self.callback)

becomes

gui.cmd_queue.p ut(self.progres sWindow.protoco l,
('WM_DELETE_WIN DOW', self.callback))

where gui is the Window object containing your gui.

I think there are some recipes like this in ASPN, that give more
detail about how to do this stuff.
Jan 25 '07 #5
In article <7x************ @ruckus.brouhah a.com>,
Paul Rubin <http://ph****@NOSPAM.i nvalidwrote:
>
self.progressWi ndow.protocol(' WM_DELETE_WINDO W', self.callback)

becomes

gui.cmd_queue.p ut(self.progres sWindow.protoco l,
('WM_DELETE_WIN DOW', self.callback))

where gui is the Window object containing your gui.

I think there are some recipes like this in ASPN, that give more
detail about how to do this stuff.
You can find a simple example at http://pythoncraft.com/ in the threads
tutorial.
--
Aahz (aa**@pythoncra ft.com) <* http://www.pythoncraft.com/

Help a hearing-impaired person: http://rule6.info/hearing.html
Jan 25 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
3075
by: Bruce Davis | last post by:
I'm having a problem on windows (both 2000 and XP) with a multi-threaded tkinter gui application. The problem appears to be a deadlock condition when a child thread pops up a Pmw dialog window in the context of a main window. The problem does not occur on HPUX or Linux. The following simple example code illustrates the problem and the work around I've come up with; However, I'd like, very much, to get rid of the kludgy work around....
2
4399
by: Michael Zhang | last post by:
My project uses Python-2.3.4 + Tkinter + PIL-1.1.4 to retrieve images from server and display those images. I created a thread (also a separate toplevel window) for displaying images and another thread for recording the frame rates (using a progress bar for visulization). The whole application worked very well once it received image data from the socket. The problem is when I tried to close that display window (click on the standard...
8
4496
by: Erik Johnson | last post by:
I am looking for some input on GUI libraries. I want to build a Python-driven GUI, but don't really understand the playing field very well. I have generally heard good things about wxPython. I happen to already own John Grayson's book about Tkinter programming, so that is rather handy if I decide to use Tkinter. I have done some things slightly more involved than "Hello World" in Tkinter - I have never used wxPython. So, basically the...
2
3594
by: Mark English | last post by:
Is there a safe way to run tkinter in a multithreaded app where the mainloop runs in a background thread ? Here's some test code demonstrating the problem. I'm running Python2.4 under Windows 2000. ----------------Code snip starts------------- from Tkinter import * def GetTkinterThread():
3
1806
by: Philippe C. Martin | last post by:
Hi, I need to pop-up in a "modless" manner some windows from an existing Tkinter loop. The following code works OK under Linux: the second window opens, shows the information, and quits cleanly when destroyed. However, under windows, I get the second window without the content (so I hang in run I guess), and both the thread and the calling process hang. Any clue ?
9
1973
by: Tuvas | last post by:
I am building a tkinter program. A part of this program is to read data from an incoming interface, and depending on the data, will display a bit of text on the tk dialog, it decodes this data, so to speak. If one command is sent, everything's just fine. When multiple are sent, the program will stop responding, and will only continue to respond after one types <ctrl>-c. The statement at fault is something like this. e1=StringVar() Label...
14
2692
by: Hendrik van Rooyen | last post by:
Hi, I get the following: hvr@LINUXBOXMicrocorp:~/Controller/libpython display.py UpdateStringProc should not be invoked for type font Aborted and I am back at the bash prompt - this is most frustrating, as there is no friendly traceback to help me guess where its coming from.
2
9577
by: Kevin Walzer | last post by:
I'm trying to decide whether I need threads in my Tkinter application or not. My app is a front end to a command-line tool; it feeds commands to the command-line program, then reads its output and displays it in a Tkinter text widget. Some of the commands are long-running and/or return thousands of lines of output. I initially thought I needed to use threading, because the GUI would block when reading the output, even when I configured...
13
3365
by: Daniel Fetchinson | last post by:
Was looking at PEP 3108, http://www.python.org/dev/peps/pep-3108/ , Is it just me or others also think that it would be a major loss to remove tkinter from the python core? PEP 3108 starts off with: Each module to be removed needs to have a justification as to why it should no longer be distributed with Python. then goes on with,
0
8831
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9374
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9325
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8244
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6796
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6076
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4607
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3315
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2215
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.