Qt相当于GObject.idle_add()

问题描述 投票:2回答:1

是否有一个与Gtk的 GObject.idle_add() Qt中的方法?

中的 gobject.idle_add() 函数添加了一个函数,只要没有更高优先级的事件待处理,就会被调用到默认的主循环中。

我的研究让我发现了一些 QTimer 诡计多端。

QtCore.QTimer().singleShot(0, self.my_method)

但它看起来有点像黑客,不那么直接, 这让我觉得它可能不是最好的选择。

有没有 "Qter "的解决方案?或者说我一开始就不应该这样做?

语境

我的GUI有一些小部件,这些小部件的作用是在情节参数上的,我使用signalsslots在小部件被点击编辑时刷新情节。我使用signalsslots来刷新情节,当小组件被点击编辑什么的时候。一个widget可能会影响其他几个widget,从而在一个用户点击时触发级联的几个刷新动作,所以我在寻找一种方法来避免在不需要的情况下多次刷新:只有最后一次刷新是有意义的。

我试过在处理这类事件时断开信号,然后在完成后再连接回来,然后 "手动 "调用刷新。我还试过使用一个标志来抑制刷新方法,这或多或少是等同的。这两种方法看起来都是无用的复杂。

我想,与其将每个widget连接到 refresh()我可以把它们连接到一个 refresh_request() 方法,该方法将引发一个 "刷新请求 "标志,并设置一个0秒的定时器来执行 refresh_if_needed() 当空闲时,如果标志被提升,则刷新。只有一次刷新会发生,因为它只在事件处理完成后执行。而且只有当至少一个小组件的数据真的被修改时,它才会刷新。此外,GUI可能会让用户感觉更流畅一些,因为事件的处理速度会更快。

编辑

而不是有 refresh_request() 提高 "刷新请求 "标志,并在空闲状态下添加一个定时器来处理该标志,我可以有 refresh_if_needed() 从主循环中永久地观察旗帜,在这种情况下。refresh_request() 将只需要处理旗帜。

这样设计会不会更好?不确定,但无论如何,我的问题可能是 "我怎么能在Qt的主循环中添加一些任务?"。这样会不会吃光CPU?我是否需要添加一个 "手动",500msec左右的暂停,在 refresh_if_needed()? 在这种情况下,我想我可以用以下方法启动它 QTimer 在正常模式下(而不是singleShot),但这是 "正常 "的方式吗?

不管怎么说,我还是对等效的 idle_add. 我心中的一个用例是一个Gtk GUI,我几年前编写的。这些按钮在线程中启动或停止声音。为了避免竞赛条件,我在主循环中启动和停止声音(代码在GitHub上 1000个LoC文件,不是删减的例子))。

qt4 pyqt4
1个回答
1
投票

相当于 g_idle_add() 可以通过为你的一个widget实现一个自定义事件,该事件通过覆盖接收器的 event() 中所示的方法。Qt 5的文档 并已在评论中指出。

一个Qt 5的例子(Qt 4与此类似)是这样的。

// Initialize event type
int customType = QEvent::registerEventType();

// Handle
bool MyWidget::event(QEvent* event) {
    if (event->type() == (QEvent::Type) customType) {
        // TODO: Do whatever your idle callback would do

        // Optional: Post event again to self if this should be repeated
        //           implementing behaviour of returning TRUE from g_idle_add callback

        return true;
    }

    // Else default handler, may want to replace QWidget with actual base of "MyWidget"
    return QWidget::event(event);
}

// Emit (given this is of type MyWidget)
QApplication::postEvent(this, new QEvent((QEvent::Type) customType));

然而,如果目标只是将信号的处理推迟到主循环,就像OP的问题一样,有一个叫做 易如反掌. 当连接插槽和信号时,请指定 Qt::QueuedConnection 对于 type 的参数 QObject::connect(). 不同的连接类型被记录在案 此处.

© www.soinside.com 2019 - 2024. All rights reserved.