problems with tkinter updates

Y

yves

I'm missing something about tkinter updates. How can I give tkinter a chance
to run?

Here's some code:

import time
import tkinter
import tkinter.scrolledtext

tk = tkinter.Tk()
f = tkinter.Toplevel(tk)
st = tkinter.scrolledtext.ScrolledText(f)
st.pack()



def update():
print('updating')
st.see(tkinter.END)
tk.after(1000, update)


input('hit enter to start')
update()
f = open('/etc/services')

for line in f:
st.insert(tkinter.END, line + '\n')
print('got it')
#time.sleep(5)
input('more?')

input('finished?')




When I do this (input('more?'), it works as expected. If I comment that line
out, then the program reads the entire file, then update the window right at
the end, even if I put a sleep in there. What can I do inside the loop to give
tk a chance?

Thanks.
 
D

Dave Angel

I'm missing something about tkinter updates. How can I give tkinter a
chance to run?

Here's some code:

import time
import tkinter
import tkinter.scrolledtext

tk = tkinter.Tk()
f = tkinter.Toplevel(tk)
st = tkinter.scrolledtext.ScrolledText(f)
st.pack()



def update():
print('updating')
st.see(tkinter.END)
tk.after(1000, update)


input('hit enter to start')
update()
f = open('/etc/services')

for line in f:
st.insert(tkinter.END, line + '\n')
print('got it')
#time.sleep(5)
input('more?')

input('finished?')




When I do this (input('more?'), it works as expected. If I comment
that line out, then the program reads the entire file, then update the
window right at the end, even if I put a sleep in there. What can I do
inside the loop to give tk a chance?
You have it backward. The question is not what you do inside your loop
to give tk a chance, but rather what do you do to make tk give you a
chance. tk doesn't "start" till you make the mainloop() method call,
and once you call that method, it won't return till the program is exiting.

So, forget about input statements inside some loop. Input isn't a gui
concept, it's for console apps. Gui apps use dialog boxes and such.
Similarly sleep(). mainloop() will sleep, when there are no events in
its queue. If you want to do work, break it into manageable chunks, and
attach each chunk to some event that tk will fire.

Beyond that, I cannot help, for I don't know tkinter. But all gui's are
similar at this level of detail.
 
Y

yves

You have it backward. The question is not what you do inside your loop to give
tk a chance, but rather what do you do to make tk give you a chance. tk
doesn't "start" till you make the mainloop() method call, and once you call
that method, it won't return till the program is exiting.

So, forget about input statements inside some loop. Input isn't a gui concept,
it's for console apps. Gui apps use dialog boxes and such. Similarly sleep().
mainloop() will sleep, when there are no events in its queue. If you want to
do work, break it into manageable chunks, and attach each chunk to some event
that tk will fire.

The input statements were there for debugging purpose... I now have got it
running without any sleep or input, I simply added a tk.update() in the loop.
It works for updating the window, but when I add buttons to that frame, they
are quite unresponsive. I'm starting to think I need to split off the reading
part into a different thread.
 
P

Peter Otten

I'm missing something about tkinter updates. How can I give tkinter a
chance to run?

Here's some code:

import time
import tkinter
import tkinter.scrolledtext

tk = tkinter.Tk()
f = tkinter.Toplevel(tk)
st = tkinter.scrolledtext.ScrolledText(f)
st.pack()



def update():
print('updating')
st.see(tkinter.END)
tk.after(1000, update)


input('hit enter to start')
update()
f = open('/etc/services')

for line in f:
st.insert(tkinter.END, line + '\n')
print('got it')
#time.sleep(5)
input('more?')

input('finished?')




When I do this (input('more?'), it works as expected. If I comment that
line out, then the program reads the entire file, then update the window
right at the end, even if I put a sleep in there. What can I do inside the
loop to give tk a chance?

Have update() (renamed to read_more() in my code) do the reading:

import sys
import tkinter
import tkinter.scrolledtext

root = tkinter.Tk()

text_window = tkinter.Toplevel()
text = tkinter.scrolledtext.ScrolledText(text_window)
text.pack()

infile = open(sys.argv[1])

def read_more():
line = next(infile, None)
if line is not None:
text.insert(tkinter.END, line)
root.after(100, read_more)
else:
text.insert(tkinter.END, "\nThat's all folks", "looney")
text.tag_configure("looney", foreground="RED")
text.see(tkinter.END)

read_more()
root.mainloop()
 
W

woooee

if line is not None: probably does not work the way you expect. You
might try
if line.strip():
Take a look at this quick example

test_lines = ["Number 1\n", "\n", ""]
for ctr, line in enumerate(test_lines):
print ctr, line
if line is not None:
print " not None"
 
P

Peter Otten

woooee wrote:

[Peter Otten]
if line is not None: probably does not work the way you expect.

It does what I expect.
You might try
if line.strip():
Take a look at this quick example

test_lines = ["Number 1\n", "\n", ""]
for ctr, line in enumerate(test_lines):
print ctr, line
if line is not None:
print " not None"

Modify your example to
test_lines = ["Number 1\n", "\n", ""]
test_lines = iter(test_lines)
while True:
.... line = next(test_lines, None)
.... if line is None:
.... print "we're done"
.... break
.... print repr(line)
....
'Number 1\n'
'\n'
''
we're done

and be enlightened ;)
 
Y

yves

Have update() (renamed to read_more() in my code) do the reading:

import sys
import tkinter
import tkinter.scrolledtext

root = tkinter.Tk()

text_window = tkinter.Toplevel()
text = tkinter.scrolledtext.ScrolledText(text_window)
text.pack()

infile = open(sys.argv[1])

def read_more():
line = next(infile, None)
if line is not None:
text.insert(tkinter.END, line)
root.after(100, read_more)
else:
text.insert(tkinter.END, "\nThat's all folks", "looney")
text.tag_configure("looney", foreground="RED")
text.see(tkinter.END)

read_more()
root.mainloop()

Thank you, this was very useful!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top