By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,871 Members | 1,209 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,871 IT Pros & Developers. It's quick & easy.

Oddities of Tkinter

P: n/a
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 (master,textvariable=e1, width=32).grid(row=44, column=4)

def disp_mes1(text):
e1.set(text)

It's the line 31.set(text) that takes so long when there's other
processes running. I've ran this program sucessfully many times on
another computer, however, when transfering to another with the same
OS, this problem was created. Any ideas as to what I might be able to
do to fix this problem? My main code is hopelessly complex to post the
entire thing, and I can't recreated the same structure with smaller
ammounts of code. Thanks for the help!

Jan 23 '06 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Tuvas wrote:
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 (master,textvariable=e1, width=32).grid(row=44, column=4)

def disp_mes1(text):
e1.set(text)

It's the line 31.set(text) that takes so long when there's other
processes running. I've ran this program sucessfully many times on
another computer, however, when transfering to another with the same
OS, this problem was created. Any ideas as to what I might be able to
do to fix this problem? My main code is hopelessly complex to post the
entire thing, and I can't recreated the same structure with smaller
ammounts of code. Thanks for the help!


The code you posted looks okay (assuming "31.set(text)" is a typo). This
is very standard usage of Tkinter, so your problem may be somewhere else
in your code. What happens if you replace disp_mes1() with

def disp_mes1(text):
print text

Does it still hang?

James
Jan 23 '06 #2

P: n/a
Nope, that's the oddest thing about it all... Perhaps the statement is
called twice or something along those lines, but there again, I can't
see how it would be...

Jan 23 '06 #3

P: n/a
Tuvas wrote:
Nope, that's the oddest thing about it all... Perhaps the statement is
called twice or something along those lines, but there again, I can't
see how it would be...


Very strange behavior can occur if the same python process instantiates
Tkinter.Tk more than once (either concurrently or at different times).
This is my best guess without any other code to look at.

James
Jan 23 '06 #4

P: n/a
Only 1 process initiated Tkinter.Tk. I guess this'll just be a tough
bug hunt... It drives me nuts that it should work, it just doesn't for
some reason... I guess I can try various things to make it work, but,
well, I would rather that it just works to start out with...

Jan 23 '06 #5

P: n/a
Tuvas wrote:
Only 1 process initiated Tkinter.Tk. I guess this'll just be a tough
bug hunt... It drives me nuts that it should work, it just doesn't for
some reason... I guess I can try various things to make it work, but,
well, I would rather that it just works to start out with...


If you have the time, buy and read Grayson
(http://www.manning.com/books/grayson) or the Tkinter section of
Programming Python by Mark Lutz--and then re-write your code. The
exercise will be well worth the time of learning and the pain of
re-writing your code.

James
Jan 23 '06 #6

P: n/a
On 23 Jan 2006 11:28:37 -0800, Tuvas <tu*****@gmail.com> wrote:
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 (master,textvariable=e1, width=32).grid(row=44, column=4)

def disp_mes1(text):
e1.set(text)

It's the line 31.set(text) that takes so long when there's other
processes running. I've ran this program sucessfully many times on
another computer, however, when transfering to another with the same
OS, this problem was created. Any ideas as to what I might be able to
do to fix this problem?


I've already seen this kind of problems when trying to do Tkinter calls
from other threads than the one from which the mainloop was started. Are
there any threads involved?

I also know that tk can take a very long time on such requests when there
are "unusual" non-ascii characters to display (CJK for example) as it
automatically looks for a font that will be able to render it; it may take
a very long time, especially if there are many installed fonts. Do you try
to display such characters?

You also don't tell us what your OS is. It may help...
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17;8(%,5.Z65\'*9--56l7+-'])"
Jan 24 '06 #7

P: n/a
I thought I mentioned that I'm running in linux, and yes, there are
threads involved. I just don't know why on one machine that it would
run so differently than another.

As to re-writing my whole code, well, I've got around 2500 lines of
code, and while re-writing would be faster I'm sure, I still don't want
to invest in the long hours to do such a thing. Especially since 90% of
the time that it will be running on the one machine that works, only a
small percentage on the other, and it will never be publically used.
It's an interface for a custom-built astronamical camera, it'd be
useless to anyone who doesn't have the very camera that we have, except
to get an idea as to how some things work.

Jan 24 '06 #8

P: n/a
On 24 Jan 2006 12:37:01 -0800, Tuvas <tu*****@gmail.com> wrote:
I thought I mentioned that I'm running in linux, and yes, there are
threads involved. I just don't know why on one machine that it would
run so differently than another.


The only secure way I found to make Tkinter mix with threads is to never
issue commands altering the graphical state of the application in another
thread than the one where the mainloop was started. Not doing that often
leads to random behaviour such as the one you have here. Fortunately, one
of the commands that seems to work in secondary threads is event_generate,
giving you a means to communicate between threads. If you have to pass
information from one thread to another, you can use a Queue.

For example:
---------------------------------------------------------------------
import threading
import time
import Queue
from Tkinter import *

## Create main window
root = Tk()

## Communication queue
commQueue = Queue.Queue()

## Function run in thread
def timeThread():
curTime = 0
while 1:
## Each time the time increases, put the new value in the queue...
commQueue.put(curTime)
## ... and generate a custom event on the main window
try:
root.event_generate('<<TimeChanged>>', when='tail')
## If it failed, the window has been destoyed: over
except TclError:
break
## Next
time.sleep(1)
curTime += 1

## In the main thread, do usual stuff
timeVar = IntVar()
Label(root, textvariable=timeVar, width=8).pack()

## Use a binding on the custom event to get the new time value
## and change the variable to update the display
def timeChanged(event):
timeVar.set(commQueue.get())

root.bind('<<TimeChanged>>', timeChanged)

## Run the thread and the GUI main loop
th=threading.Thread(target=timeThread)
th.start()

root.mainloop()
---------------------------------------------------------------------

This obvioulsy complicates things a bit, but it may work far better.
Please note that the 'when' option *must* be specified in the call to
event_generate and *must not* be 'now'. If it's not specified or if it's
'now', Tkinter may directly execute the binding in the secondary thread's
context.

HTH

(BTW, please quote the question to which you're replying. You're fortunate
I still had your original question in mind, or I would have had no idea of
what you were talking about...)
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17;8(%,5.Z65\'*9--56l7+-'])"
Jan 25 '06 #9

P: n/a
Tuvas,

I fully agree with Eric's post above. You may additionnaly have to kill
the main window before exit, to avoid a nasty thread related error
message and occasionally some zombie procs:

import Tkinter,atexit
top=Tkinter.Tk()
..../...
atexit.register(lambda top=top: top.destroy())
top.mainloop()

Jan 25 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.