3

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

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

动画是通过QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest))周期性调用实现的,然后每次窗口接收到时调用redrawing 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 上。

4

3 回答 3

1

这可能是一个 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()- 这就是它的用途。

于 2013-09-03T20:42:37.803 回答
0

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

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

  1. 如果您的 MainThread 调用 PostEvent(如果您正在使用主 gui 线程中的计时器),则将它们移至工作线程中的后端功能,并在完成后将其移至 postEvent。
    • 你在你的 render() 之后调用 QCoreApplication::processEvents();MainThread 中的函数。这将帮助系统在继续之前处理事件循环中的所有其他事件

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

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

于 2013-09-04T01:18:52.360 回答
0

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

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

于 2013-09-07T17:50:06.570 回答