There is any event for a Gtk.Button that would execute the code repeatedly while the button is being pressed?

StackOverflow https://stackoverflow.com/questions/19439045

Question

There is any event for a Gtk.Button that would execute the code repeatedly while the button is being pressed?

Let's supose I have the following code written in Python 3 and using PyGObject. I'd like to have the message "Hi" been repeadly printed on the screen while the user is holding down the mouse left button over the button (clicking and holding).

There is any other event I can use instead of clicked or any other solution? Thanks.

from gi.repository import Gtk

class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.button = Gtk.Button("Hi Printer")
        self.button.connect("clicked", self.on_button_clicked)
        self.add(self.button)
        self.connect("delete-event", Gtk.main_quit)
    def on_button_clicked(self, widget):
        print("Hi")

window = Window()
window.show_all()
Gtk.main()
Was it helpful?

Solution

Adapted from tcaswell's edited answer, but avoiding the extra call to print_hi() after the button is released:

from gi.repository import Gtk, GObject

class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.button = Gtk.Button("Hi Printer")
        self.button.connect("pressed", self.on_button_clicked)
        self.button.connect("released", self.on_button_released)
        self.add(self.button)
        self.connect("delete-event", Gtk.main_quit)

    def on_button_clicked(self, widget):
        # kick off time out
        timeout = 50
        self._timeout_id = GObject.timeout_add(timeout, self.print_hi)

    def on_button_released(self, widget):
        # remove timeout
        GObject.source_remove(self._timeout_id)
        self._timeout_id = 0 # better safe than sorry

    def print_hi(self):
        print 'hi'
        # repeat until the source is removed
        return True

window = Window()
window.show_all()
Gtk.main()

OTHER TIPS

from gi.repository import Gtk, GObject

class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.button = Gtk.Button("Hi Printer")
        self.button.connect("pressed", self.on_button_clicked)
        self.button.connect("released", self.on_button_released)
        self.add(self.button)
        self.connect("delete-event", Gtk.main_quit)

    def on_button_clicked(self, widget):
        # arm repeater
        self._repeat = True
        # trigger printing
        self.print_hi()

    def on_button_released(self, widget):
        # disarm repeater
        self._repeat = False

    def print_hi(self):
        print 'hi'
        # tune timeout for repeat rate
        timeout = 50
        # if should still be repeating
        if self._repeat:
            # arm timer, with call back to this function
            GObject.timeout_add(timeout, self.print_hi)

window = Window()
window.show_all()
Gtk.main()

Issue before is 'clicked' is up-down on the button, 'pressed' is down and 'released' is up.

Also updated to use the correct timer.

It turns out the timeout function in gtk can automatically re-set, so this can be done even more simply:

from gi.repository import Gtk, GObject


class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.button = Gtk.Button("Hi Printer")
        self.button.connect("pressed", self.on_button_clicked)
        self.button.connect("released", self.on_button_released)
        self.add(self.button)
        self.connect("delete-event", Gtk.main_quit)

    def on_button_clicked(self, widget):
        # arm repeater
        self._repeat = True
        # kick off time out
        timeout = 50
        GObject.timeout_add(timeout, self.print_hi)

    def on_button_released(self, widget):
        # disarm repeater
        self._repeat = False

    def print_hi(self):
        print 'hi'
        # if should still be repeating
        return self._repeat

window = Window()
window.show_all()
Gtk.main()

example

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top