qt中如何同步应用程序和显示器的刷新率?

Posted

技术标签:

【中文标题】qt中如何同步应用程序和显示器的刷新率?【英文标题】:How to sync the refresh rate of the application and the monitor in qt? 【发布时间】:2020-02-13 00:49:53 【问题描述】:

我写了一个小 c++/qt 应用程序,在实际光标位置绘制一个自制光标。为了分别最小化实际光标位置和绘制的偏移量的延迟,我的 QWidget 尽可能快地自我更新。

部分构造函数:

QTimer *Timer = new QTimer(this);
connect(Timer, SIGNAL(timeout()), this, SLOT(update()));
Timer->start();

绘画事件:

void Widget::paintEvent(QPaintEvent* event) 
    auto t1 = std::chrono::high_resolution_clock::now();
    std::cerr << "Duration Cycle: " << std::chrono::duration_cast<std::chrono::milliseconds>(t1 - LastT1).count() << std::endl;
    LastT1 = t1;

    // Draw Cursor
    POINT LpPoint;
    GetCursorPos(&LpPoint);
    QPoint CursorPos(LpPoint.x, LpPoint.y);
    CursorPos = mapFromGlobal(CursorPos);
    QPainter Painter(this);
    Painter.drawEllipse(CursorPos, 20, 20);

    std::cerr << "Duration Paintevent: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t1).count() << std::endl;


现在我有两个问题:

    paintevent 的持续时间约为一毫秒。一个周期的持续时间在 10 到 15 毫秒之间。 Qt 在此期间做了什么?更多信息: update() 和 repaint() 之间没有区别,如果我将计时器设置为固定整数,例如Timer-&gt;start(2);。降低显示器的分辨率会缩短循环持续时间。

    我使用的是 60 Hz 显示器,所以如果我能够将更新与显示器的刷新率同步,我真的不需要更高的刷新率。那可能吗?我对此进行了一些研究,但没有发现任何真正有用的东西。

我希望我没有错过一些基本的东西。我会感谢任何意见。

【问题讨论】:

【参考方案1】:

一个周期的持续时间在 10 到 15 毫秒之间。什么 Qt同时做了吗?

它很可能处于休眠状态,和/或还倾向于 Qt 事件循环负责的其他业务。请注意,在 Windows 上,进程的计时器默认为具有 10mS 粒度的低分辨率机制(因此,如果您希望 Windows 进程一次能够休眠少于 10mS,您需要调用 timeBeginPeriod(1) at程序的开始)。

将更新与显示器的刷新率同步。那可能吗?

原则上这是可能的,但 Qt 的 QWidget API 并不是真正为那种级别的控制而设计的(QWidgets 与其说是一个游戏/多媒体 API,不如说是一个经典的桌面应用程序 GUI,所以它更侧重于获取内容正确,而不是保证最紧迫的时间)。如果您可以切换到使用 QML 而不是旧的 QWidgets API,QML 有 some support 用于同步到监视器刷新。另一种可能性是通过 OpenGL 在 QOpenGLWindow 内绘制图形; QOpenGLWindow 类还具有与刷新率同步的能力(有关其 frameSwapped() 信号,请参阅文档)。

顺便说一句,将输出写入stdout(又名std::cout)和/或stderr(又名std::cerr)可能会非常慢,并且在您发布的程序中这样做可能会浪费您的时间测量了很多。更好的方法是收集计时数据,但只是将其存储在某种数据结构中,直到您完成测量,然后仅在最后(例如,当您退出程序时)打印出测量值,以便打印值不会影响值的准确性。

【讨论】:

以上是关于qt中如何同步应用程序和显示器的刷新率?的主要内容,如果未能解决你的问题,请参考以下文章

Qt 4 中的 OpenGL 更新率

[android数据库同步]架构一种Android界面数据同步刷新机制

Qt:如何在模型/视图设置中同步对来自多个线程的数据的访问?

Qt系列文章之三十(基于QThread的线程同步概述)

Qt系列文章之三十(基于QThread的线程同步概述)

QT自定义QTextEdit实现大数据的实时刷新显示