pygtk glib.timeout_add():如何判断计时器是否没有被销毁?
在我的应用程序中,我使用一个函数来显示带有超时的 GtkInfoBars (如所述 https://stackoverflow.com/a/1309257/406281< /a>) 感谢 glib.timeout_add_seconds()。
我知道 glib.timeout_add_seconds() 应该设置一个定期调用的函数,直到该函数返回 False 。
我没有这样做,但一切都按预期进行。这非常简单。这是我的代码:
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。提问时间。看看我在最后一行做了什么。简单来说,这样可以吗?第二次调用 bar.hide() 失败后超时会自行破坏吗?或者我是否累积了额外的绝育超时,[技术上]每 5 秒唤醒一次,耗尽资源?
作为附录:
如果,正如我怀疑的那样,这很糟糕,并且我确实需要返回 False 来破坏超时,我需要一些帮助 - 我不知道如何解决为了满足这些条件:我需要同时允许多个 InfoBar,每个 InfoBar 仍然保持连接到自己的计时器和按钮响应信号(就像现在的代码一样)OR我需要每个新的信息栏来替换以前的信息栏(我不知道如何在不继承以前的信息栏的计时器的情况下做到这一点——它会变得混乱)。
感谢您的阅读!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于
bar.hide
被多次调用,我认为这不会发生,因为据我所知,它应该足以返回一个被评估为False
的值并且bar.hide
返回None
这应该足够了。但是,如果您想完全确定,您可以使用以下内容进行验证:在本例中,回调也返回
None
并且仅被调用一次,正如您从的输出中看到的那样>标准输出
。关于你的最后一个问题,我想说这已经是一种可以接受的方式,拥有多个信息栏,每个信息栏都有一个单独的计时器。如果我遗漏了什么,请添加更多信息。
Regarding
bar.hide
being called more than once, I think that's not happening because, as far as I know, it should be enough to return a value that is evaluated asFalse
andbar.hide
returnsNone
which should be enough. However, if you want to make completely sure, you can verify with something like this:In this example, the callback returns
None
as well and is called just once as you can see from the output tostdout
.Regarding your final question, I'd say this is already an acceptable way of having multiple infobars with a separate timer for each one. Please add more information if I'm missing something.
Widget.hide
始终返回 None,而glib.timeout_add_seconds
将其视为与 False 相同。因此,您的计时器将始终在运行一次后终止。hide
有可能会被调用两次(当用户单击“确定”时和 5 秒超时时),但没关系。所以是的,你的代码没问题。编辑:刚刚意识到一些事情。每次函数运行时,您都会创建一个新的信息栏,然后仅隐藏它。不要使用
hide
,而是使用destroy
,以便正确清理它。并不太复杂;只需重复使用相同的信息栏即可。记录
glib.timeout_add_seconds
的返回值,然后在替换信息栏内容的同时,用glib.source_remove
。您提供的两个选择之间存在可用性权衡(干净的 UI 与确保用户不会错过重要信息),但这是另一个主题,也许并不那么重要。
Widget.hide
always returns None, whichglib.timeout_add_seconds
treats identically to False. Thus, your timer will always terminate after running once. There is a possibility thathide
will 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
, usedestroy
so 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.