当用户打开菜单或调整窗口大小时,QMainWindow停止接收QEvent::UpdateRequest



MyWindow,它继承自QMainWindow。MyWindow包含一个显示动画的QGLWidget。

问题是,每当我打开菜单或调整窗口大小时,动画都会暂停。

动画是通过周期性地调用QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest))来实现的,然后每次窗口接收到QEvent::UpdateRequest时都调用重绘,如下所示:

bool MyWindow::event(QEvent *event)
{
    qDebug() << event;
    switch (event->type())
    {
        case QEvent::UpdateRequest:
            render();
            return true;
        default:
            return QMainWindow::event(event);
    }
}

qDebug()可以看出,当菜单打开或窗口正在调整大小时,窗口将停止接收更新请求事件。

QMainWindow/QWidget上是否有设置使其继续接收更新请求事件?或者有更好的方法来实现动画吗?

编辑:我在Mac OS X上。

这可能是一个Qt错误。我会调查的。

唉,你的代码太复杂了。

  1. postEvent应该简单地由this->update()代替。它在幕后为您发布活动。

  2. 可以简单地将QTimer实例的信号连接到widget, SLOT(update())。如果要保存在QObject实例上,请使用QBasicTimer并重新实现timerEvent,如下所示:void MyWidget::timerEvent(QTimerEvent* ev) { if (ev.timerId() == m_timer.timerId()) update(); }

  3. 不需要处理event()的重新实现。只需重新实现paintEvent()——这就是它的用途。

Qt GUI更新正在MainThread上执行。所以,若同时拥有许多gui功能,那么缓慢的gui响应是合理的。所以一般来说,不要用太多繁重的函数调用来重载MaiThread。

加速GUI响应的可能解决方案。

  1. 如果PostEvent是由您的MainThread调用的(如果您使用的是来自主gui线程的计时器),请将其移动到中的后端功能工作线程和postEvent
    • 在render()之后调用QCoreApplication::processEvents();函数。这将有助于系统在继续之前处理事件循环中的所有其他事件

请查看以下链接如何改进GUI响应

注意:当创建和触发计时器时,默认情况下它将在您的线程中运行,它不会启动另一个线程。

由于我没有从Kuba Ober那里听到任何关于这可能是Qt错误的消息,我继续提交了一份错误报告:https://bugreports.qt-project.org/browse/QTBUG-33382

通过更直接地调用render()函数,我能够部分地解决这个问题——也就是说,不用发送事件、接收事件并让事件处理程序调用该函数。我用一个调度队列(但不是主调度队列,因为它与默认的运行循环绑定,所以它也有同样的问题)完成了这项工作。然而,在多个线程上使用QGLWidget是很困难的。在尝试使用moveToThread()函数来实现这一功能一段时间后,并考虑到项目中涉及的其他因素,我决定使用Qt之外的其他东西来显示此窗口。

相关内容

  • 没有找到相关文章

最新更新