如何在qt中同步应用程序和监视器的刷新率?

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

我编写了一个小c ++ / qt应用程序,该应用程序在实际光标位置上绘制了一个自制的光标。为了使等待时间分别最小化实际光标位置和绘制位置的偏移,我的QWidget尽可能快地更新自身。

部分构造函数:

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

paintevent:

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 vLpPoint;
    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;

}

现在我有两个问题:

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

  2. 我使用的是60 Hz监视器,因此,如果我能够将更新与监视器的刷新率同步,我实际上并不需要更高的刷新率。那可能吗?我对此进行了一些研究,但没有发现任何真正的帮助。

我希望我不会错过一些基本的东西。我将不胜感激。

c++ windows qt frame-rate
1个回答
0
投票

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

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

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

原则上是可能的,但是Qt的QWidget API并非真正针对该控制级别而设计的(QWidgets少了游戏/多媒体API,而更多的是经典的桌面应用程序GUI,因此它更着重于获取内容比保证最紧的时间安排更合适)。如果您可以切换为使用QML而不是较旧的QWidgets API,则QML具有some support用于同​​步到显示器刷新。另一种可能性是在QOpenGLWindow内通过OpenGL绘制图形。 QOpenGLWindow类还具有与刷新率同步的功能(请参见有关frameSwapped()信号的文档)。

Btw注意,将输出写入stdout(aka std::cout)和/或stderr(aka std::cerr)可能会相当慢,并且在发布的程序中这样做可能会导致计时测量结果中断很多。更好的方法是收集时序数据,但仅将其存储在某种数据结构中,直到完成测量为止,然后仅在最后(例如,退出程序时)打印出测量值,以便打印值不会影响值的准确性。

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