tkinter redraw rates

fronagzen at gmail.com fronagzen at gmail.com
Thu Jul 18 00:38:00 EDT 2013


On Thursday, July 18, 2013 9:07:24 AM UTC+8, Dave Angel wrote:
> On 07/17/2013 08:44 PM, fronagzen at gmail.com wrote:
> > On Thursday, July 18, 2013 1:38:34 AM UTC+8, Dave Angel wrote:
> >> On 07/17/2013 09:18 AM, fronagzen at gmail.com wrote:
> >>> On Wednesday, July 17, 2013 7:42:45 PM UTC+8, Dave Angel wrote:
> >>>> On 07/17/2013 07:10 AM, fronagzen at gmail.com wrote:
> >>>>> On Wednesday, July 17, 2013 6:07:22 PM UTC+8, Dave Angel wrote:
> >>>>>> On 07/16/2013 11:04 PM, fronagzen at gmail.com wrote:
> >>>>>>> Noted on the quoting thing.
> >>>>>>> Regarding the threading, well, first, I'm not so much a programmer as someone who knows a bit of how to program.
> >>>>>>> And it seems that the only way to update a tkinter window is to use the .update() method, which is what I was experimenting with. Start up a new thread that just loops the .update() with a 1ms sleep until the download is done. It seems to work, actually.
> >>>>>> update() is to be used when it's too awkward to return to mainloop.  In
> >>>>>> my second approach, you would periodically call it inside the processing
> >>>>>> loop.  But unless tkinter is unique among GUI's, it's unsafe to do that
> >>>>>> in any thread besides the GUI thread.
> >>>>>> DaveA
> >>>>> Yes, based on advice from this thread, I'm doing that. From my main thread, I create a thread that handles the download while updating a variable that the mainloop displays as a text output, and in that mainloop, I have a while loop that updates the GUI until the downloading is done.
> >>>> I can't figure out what you're really doing, since each message from you
> >>>> says something different.  You don't need a separate while loop, since
> >>>> that's exactly what app.mainloop() is.
> >>>> --
> >>>> DaveA
> 
> >>> Hm. My apologies for not being very clear. What I'm doing is this:
> >>>           self.loader_thread = Thread(target=self.loadpages,
> >>>                                       name="loader_thread")
> >>>           self.loader_thread.start()
> >>>           while self.loader_thread.isAlive():
> >>>               self.root_window.update()
> >>>               sleep(0.05)
> >>> Where loadpages is a function defined elsewhere.
>
> >> Presumably this fragment is from a method of some class you've written.
> >>    Is it an event handler, or is this happening before you finish setting
> >> up the GUI?  Somewhere at top-level, you're supposed to fall into a call
> >> to mainloop(), which doesn't return till the user cancels the app.
> >> --
> >> DaveA
> 
> > This is, indeed, an event handler from a class for my GUI. My entire GUI is a bit large, so I'll not copy the entire thing here, but it roughly goes:
> > class GUI(object):
> >      def __init__(self):
> >          [stuff]
> >      def init_button(self):
> >          self.execute = ttk.Button(self.input_frame, text='Tally',
> >                                    command=self.execute_now)
> >          self.execute.grid(column=1, row=2, sticky=(N, S, E, W), columnspan=4)
> >      def execute_now(self):
> >          [stuff]
> >          self.loader_thread = Thread(target=self.loadpages,
> >                                      name="loader_thread")
> >          self.loader_thread.start()
>             self.root_window.after(100, self.test_thread)
>             return
> >          while self.loader_thread.isAlive():
> >              self.root_window.update()
> Nope - don't use that.  Instead, post an event on the queue, and return 
> to the mainloop() from whence we came.
>          def test_thread(self):
>             if self.loader_thread.isAlive():
>                 self.root_window.after(100, self.test_thread)
>                 return
>             [morestuff]
> >              sleep(0.05)
> >          [morestuff]
> > if __name__ == "__main__":
> >      APP = GUI()
> >      APP.root_window.mainloop()
> I probably don't have it quite right, but hopefully you'll get the idea. 
>   self.test_thread() is now a new event that will get repeatedly 
> invoked, to do the check on the thread status.  It returns rapidly 
> unless the condition has occurred.
> There are other things that should be done, like blocking the specific 
> events that would create duplicate threads.
> -- 
> 
> DaveA

I see, though it should be noted that your method doesn't actually block the rest of the even handler code from running, had to fiddle with it a bit to get that to work. May I ask what exactly is the rationale behind implementing it like this, though?



More information about the Python-list mailing list