pygtk glib.timeout_add():如何判断计时器是否没有被销毁?

发布于 2024-12-29 00:13:52 字数 1194 浏览 3 评论 0原文

在我的应用程序中,我使用一个函数来显示带有超时的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜柠檬 2025-01-05 00:13:52

关于 bar.hide 被多次调用,我认为这不会发生,因为据我所知,它应该足以返回一个被评估为 False 的值并且 bar.hide 返回 None 这应该足够了。但是,如果您想完全确定,您可以使用以下内容进行验证:

import gtk, glib

def callback():
    print 'called'

glib.timeout_add_seconds(1, callback)
gtk.main()

在本例中,回调也返回 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 as False and bar.hide returns None which should be enough. However, if you want to make completely sure, you can verify with something like this:

import gtk, glib

def callback():
    print 'called'

glib.timeout_add_seconds(1, callback)
gtk.main()

In this example, the callback returns None as well and is called just once as you can see from the output to stdout.

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.

腹黑女流氓 2025-01-05 00:13:52

Widget.hide 始终返回 None,而 glib.timeout_add_seconds 将其视为与 False 相同。因此,您的计时器将始终在运行一次后终止。 hide 有可能会被调用两次(当用户单击“确定”时和 5 秒超时时),但没关系。所以是的,你的代码没问题。

编辑:刚刚意识到一些事情。每次函数运行时,您都会创建一个新的信息栏,然后仅隐藏它。不要使用 hide,而是使用 destroy,以便正确清理它。

...或者我需要每个新的 InfoBar 来替换任何以前的 InfoBar(我无法弄清楚如何在不继承前一个 InfoBar 的计时器的情况下执行此操作 - 它会变得混乱)。

并不太复杂;只需重复使用相同的信息栏即可。记录glib.timeout_add_seconds的返回值,然后在替换信息栏内容的同时,用glib.source_remove

您提供的两个选择之间存在可用性权衡(干净的 UI 与确保用户不会错过重要信息),但这是另一个主题,也许并不那么重要。

Widget.hide always returns None, which glib.timeout_add_seconds treats identically to False. Thus, your timer will always terminate after running once. There is a possibility that hide 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, use destroy so it gets properly cleaned up.

... 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).

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 with glib.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文