In my application I use a function to show GtkInfoBars with a timeout (as described https://stackoverflow.com/a/1309257/406281) thanks to glib.timeout_add_seconds().
I understand that glib.timeout_add_seconds() is supposed to set a function to be called at regular intervals until said function returns False.
I’m not doing that, but everything works as expected. It’s perfectly simple. Here’s my code:
def infobar(self, message, msgtype=gtk.MESSAGE_INFO, timeout=5):
bar = gtk.InfoBar()
bar.set_message_type(msgtype)
bar.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
bar.connect("response", lambda *args: bar.hide())
self.vb2.pack_end(bar, False, False)
label = gtk.Label()
label.set_markup(message)
content = bar.get_content_area()
content.add(label)
label.show()
bar.show()
if timeout:
glib.timeout_add_seconds(timeout, bar.hide)
SO. Question time. Look at what I did in the last line. Simply put, is this okay? Will the timeout destroy itself after the second call to bar.hide() fails? Or am I accumulating extra neutered timeouts that will wake up every 5 seconds [technically] using up resources?
As an addendum:
If, as I suspect, this is bad, and I really do need to return False to destroy the timeouts, I need some help — I can’t figure out how to play around with the code in order to satisfy these conditions: I need to allow multiple InfoBars at the same time, with each still staying connected to their own timer and button-response signal (as the code is now) OR I need each new InfoBar to replace any previous one (I can’t figure out how to do this without inheriting the timer from the previous InfoBar–it gets messy).
Thanks for reading!
Widget.hidealways returns None, whichglib.timeout_add_secondstreats identically to False. Thus, your timer will always terminate after running once. There is a possibility thathidewill be called twice (when the user clicks OK and at the 5 s timeout) but that’s alright. So yes, your code is fine.Edit: Just realised something. You’re creating a new info bar every time the function runs, then only hiding it. Instead of using
hide, usedestroyso it gets properly cleaned up.It’s not too complicated; just reuse the same info bar. Record the return value of
glib.timeout_add_seconds, then while replacing the content of the info bar, kill the previous timer withglib.source_remove.There are usability trade-offs between the two choices you present (clean UI vs. making sure the user doesn’t miss important info) but that’s another topic and perhaps not that important.