Button

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Button

psao pollard-flamand
You know when you click a tkinter button and the window usually freezes until its done? Does any one know how to stop that?

Sent from my Windows Phone

_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Button

Michael O'Donnell
On Wed, May 18, 2011 at 5:01 PM, psao pollard-flamand
<[hidden email]> wrote:
> You know when you click a tkinter button and the window usually freezes
> until its done? Does any one know how to stop that?

This may or may not fix your problem, depending on your updating problem.

Instead of:

    Button(tkwin, text="Go", command=dosomething)

Put instead:

def delayedDoSomething():
       tkwin.after(100, dosomething)

Button(tkwin, text="Go", command=delayedDoSomething)

The net effect is taking your button command off the event queue
for a bit, letting the button to redraw itself or whatever needs to be done.

if the work done by the command invoked by the button is quite cpu intensive,
I do somethink like the following:


Class  XXX(Toplevel):

    def updateInterface(self):
        self.updateDisplay()
        if not self.DONE:
            self.after(100, self.updateInterface)

    def doSomething(self):
        # A flag used by updateInterface to know when to quit
        self.DONE=False

        # The following will return, but call itself every second
        self.updateInterface()

        # Now do the work
        for fpath in glob.glob("*.*"):
           self.processFile(fpath)
           # next line is important I think to ensure the display proc
gets a chance
           self.update()

        # work finished, tell updateInterface to quit
        self.DONE=True
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Button

Peter Milliken-2
Michael offers excellent solutions.

When the work being done is cpu intensive (and the application allows :-)), I often use threading i.e. the button runs a command that starts a Python thread which goes off and does what needs to  be done.

If the job being performed is that intensive then you probably want GUI elements to show progress - in which case you can communicate to the thread via pipes/queues and run another task that looks after the "communications" and is responsible for updating GUI elements - such as progress bars.

I do this sort of thing a lot in my GUI's - just depends on what you are doing though. But threading isn't for everyone - if you are used to straight "linear" thinking in your programming then threads can take a bit of mind bending to get your head around - but once you have then all problems seem to be solved better through using threads :-)



On Thu, May 19, 2011 at 2:08 AM, Michael O'Donnell <[hidden email]> wrote:
<snip>
 
if the work done by the command invoked by the button is quite cpu intensive,
I do somethink like the following:

<snip>

_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Button

Michael O'Donnell
yes, Threading is the other solution.

One needs to be very careful not to call any Tkinter elements
from the child threads, as it seems this can cause freezes.

I used threads for a while, but could not solve the odd cases
where my interface froze until the child thread finished.

In any case, see an example at:

http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/

On Wed, May 18, 2011 at 11:14 PM, Peter Milliken
<[hidden email]> wrote:

> Michael offers excellent solutions.
> When the work being done is cpu intensive (and the application allows :-)),
> I often use threading i.e. the button runs a command that starts a Python
> thread which goes off and does what needs to  be done.
> If the job being performed is that intensive then you probably want GUI
> elements to show progress - in which case you can communicate to the thread
> via pipes/queues and run another task that looks after the "communications"
> and is responsible for updating GUI elements - such as progress bars.
> I do this sort of thing a lot in my GUI's - just depends on what you are
> doing though. But threading isn't for everyone - if you are used to straight
> "linear" thinking in your programming then threads can take a bit of mind
> bending to get your head around - but once you have then all problems seem
> to be solved better through using threads :-)
>
>
> On Thu, May 19, 2011 at 2:08 AM, Michael O'Donnell <[hidden email]>
> wrote:
>>
>> <snip>
>
>
>>
>> if the work done by the command invoked by the button is quite cpu
>> intensive,
>> I do somethink like the following:
>>
>> <snip>
>
> _______________________________________________
> Tkinter-discuss mailing list
> [hidden email]
> http://mail.python.org/mailman/listinfo/tkinter-discuss
>
>
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Button

Peter Milliken-2
Do you use mtTkinter Michael?

Best package since "sliced bread" (as the saying goes) - I haven't had any issues with GUI elements and tasking since using it. It has cured ALL of my issues with tasks and Tkinter GUI's freezing and behaving weirdly since I first discovered it.

In my threads (checked my latest program), I just pass the progress bar as an argument to the thread - the argument is actually a class wrapper that "hides" the GUI progress bar from the thread program. So the thread performs the actual GUI updates directly.

The class interface uses the same calls as a Queue provides - that way I can invoke the thread program from either a GUI or a command line interface - in the later case I use a Queue instance as the argument and have the command line part of the program read the data out and print it directly to the screen.

I think that is all I do to get Tkinter and threads working together...

Hope this makes sense :-)

Peter

On Thu, May 19, 2011 at 8:28 AM, Michael O'Donnell <[hidden email]> wrote:
yes, Threading is the other solution.

One needs to be very careful not to call any Tkinter elements
from the child threads, as it seems this can cause freezes.

I used threads for a while, but could not solve the odd cases
where my interface froze until the child thread finished.

In any case, see an example at:

http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/

On Wed, May 18, 2011 at 11:14 PM, Peter Milliken
<[hidden email]> wrote:
> Michael offers excellent solutions.
> When the work being done is cpu intensive (and the application allows :-)),
> I often use threading i.e. the button runs a command that starts a Python
> thread which goes off and does what needs to  be done.
> If the job being performed is that intensive then you probably want GUI
> elements to show progress - in which case you can communicate to the thread
> via pipes/queues and run another task that looks after the "communications"
> and is responsible for updating GUI elements - such as progress bars.
> I do this sort of thing a lot in my GUI's - just depends on what you are
> doing though. But threading isn't for everyone - if you are used to straight
> "linear" thinking in your programming then threads can take a bit of mind
> bending to get your head around - but once you have then all problems seem
> to be solved better through using threads :-)
>
>
> On Thu, May 19, 2011 at 2:08 AM, Michael O'Donnell <[hidden email]>
> wrote:
>>
>> <snip>
>
>
>>
>> if the work done by the command invoked by the button is quite cpu
>> intensive,
>> I do somethink like the following:
>>
>> <snip>
>
> _______________________________________________
> Tkinter-discuss mailing list
> [hidden email]
> http://mail.python.org/mailman/listinfo/tkinter-discuss
>
>


_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Button

Michael O'Donnell
Hi Peter.

  I have somehow not sen mtTkinter before. Looks great, will try it out.

Mick

On Thu, May 19, 2011 at 3:18 AM, Peter Milliken
<[hidden email]> wrote:

> Do you use mtTkinter Michael?
> Best package since "sliced bread" (as the saying goes) - I haven't had any
> issues with GUI elements and tasking since using it. It has cured ALL of my
> issues with tasks and Tkinter GUI's freezing and behaving weirdly since I
> first discovered it.
> In my threads (checked my latest program), I just pass the progress bar as
> an argument to the thread - the argument is actually a class wrapper that
> "hides" the GUI progress bar from the thread program. So the thread performs
> the actual GUI updates directly.
> The class interface uses the same calls as a Queue provides - that way I can
> invoke the thread program from either a GUI or a command line interface - in
> the later case I use a Queue instance as the argument and have the command
> line part of the program read the data out and print it directly to the
> screen.
> I think that is all I do to get Tkinter and threads working together...
> Hope this makes sense :-)
> Peter
>
> On Thu, May 19, 2011 at 8:28 AM, Michael O'Donnell <[hidden email]>
> wrote:
>>
>> yes, Threading is the other solution.
>>
>> One needs to be very careful not to call any Tkinter elements
>> from the child threads, as it seems this can cause freezes.
>>
>> I used threads for a while, but could not solve the odd cases
>> where my interface froze until the child thread finished.
>>
>> In any case, see an example at:
>>
>>
>> http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/
>>
>> On Wed, May 18, 2011 at 11:14 PM, Peter Milliken
>> <[hidden email]> wrote:
>> > Michael offers excellent solutions.
>> > When the work being done is cpu intensive (and the application allows
>> > :-)),
>> > I often use threading i.e. the button runs a command that starts a
>> > Python
>> > thread which goes off and does what needs to  be done.
>> > If the job being performed is that intensive then you probably want GUI
>> > elements to show progress - in which case you can communicate to the
>> > thread
>> > via pipes/queues and run another task that looks after the
>> > "communications"
>> > and is responsible for updating GUI elements - such as progress bars.
>> > I do this sort of thing a lot in my GUI's - just depends on what you are
>> > doing though. But threading isn't for everyone - if you are used to
>> > straight
>> > "linear" thinking in your programming then threads can take a bit of
>> > mind
>> > bending to get your head around - but once you have then all problems
>> > seem
>> > to be solved better through using threads :-)
>> >
>> >
>> > On Thu, May 19, 2011 at 2:08 AM, Michael O'Donnell
>> > <[hidden email]>
>> > wrote:
>> >>
>> >> <snip>
>> >
>> >
>> >>
>> >> if the work done by the command invoked by the button is quite cpu
>> >> intensive,
>> >> I do somethink like the following:
>> >>
>> >> <snip>
>> >
>> > _______________________________________________
>> > Tkinter-discuss mailing list
>> > [hidden email]
>> > http://mail.python.org/mailman/listinfo/tkinter-discuss
>> >
>> >
>
>
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Button

Alan Gauld
In reply to this post by psao pollard-flamand

"psao pollard-flamand" <[hidden email]> wrote

> You know when you click a tkinter button and the
> window usually freezes until its done?

Actually it doesn't *usually* freeze because most Tkinter
apps are designed to prevent that :-)

> Does any one know how to stop that?

The key here is that GUI event handlers are intended
to be short functions that do one thing at a time. If they
have to do more intensive and time consuming actions
then the event handler will either:
a) launch another function to do that, using a different
     thread if necessary.
b) open a modal dialog that displays progress (or at
    the very least a warning).

The objective should be to habd control back to the
event loop as fast as possible so you can respond
to the next event - which might, after all, be a cancel
operation!

HTH,


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/


_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss