4

I'm working on programming some application and I would like to create while loop when button is clicked and if it's clicked again to stop it. This is the code for button:

self.btnThisOne = gtk.Button("This one")
self.btnThisOne.connect("clicked", self.startLoop)

The code for startLoop def would be:

def startLoop(self):
    while self.btnThisOne?(is_clicked)?:
        #do something

How to do that?

1 Answer 1

3

Unfortunately, you cannot just have an unconstrained while loop running in the main thread of your application. That would block the main gtk event loop and you won't be able to process any more events. What you probably want to do is spawn a thread.

Have you considered using a ToggleButton instead of GtkButton? The closest thing to an is_clicked method is is_active and you'll find that in toggle buttons.

Here's an example of starting and controlling a thread depending on the state of a toggle button (replace triggered with clicked and ToggleButton with Button if you want a regular button):

import gtk, gobject, threading, time

gobject.threads_init()

window = gtk.Window()
button = gtk.ToggleButton('Start Thread')

class T(threading.Thread):
    pause = threading.Event()
    stop = False

    def start(self, *args):
        super(T, self).start()

    def run(self):
        while not self.stop:
            self.pause.wait()
            gobject.idle_add(self.rungui)
            time.sleep(0.1)

    def rungui(self):
        pass # all gui interaction should happen here

thread = T()
def toggle_thread(*args):
    if not thread.is_alive():
        thread.start()
        thread.pause.set()
        button.set_label('Pause Thread')
        return

    if thread.pause.is_set():
        thread.pause.clear()
        button.set_label('Resume Thread')
    else:
        thread.pause.set()
        button.set_label('Pause Thread')

button.connect('toggled', toggle_thread, None)

window.add(button)
button.show()
window.show()
gtk.main()

This PyGTK FAQ answer might prove helpful. Cheers.

Sign up to request clarification or add additional context in comments.

6 Comments

Can I put functions for start threading into existing class? How to create only Start and Stop functions without pause?
To stop the thread, simply thread.stop = True. Keep in mind that once a thread terminates it cannot be started again (you'll have to create a new one).
I would like to start threading from different class&method, but I doesn't work - pastebin.com/xmHqK6Qc . Is it possible to send data to T.run() method or to create method inside class Start to start threading with method in this class?
Okay, now I achieved out how to start threading from method from different class. It is possible to transport some data to toggle_thread and apply it to T.run and T.rungui?
Yes. Use a thread safe data structure like a Queue and share it between the main-thread and the new thread.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.