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



我写了一个小的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;
}

现在我有两个问题:

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

  2. 使用的是 60 Hz 显示器,因此如果我能够将更新与显示器的刷新率同步,我真的不需要更高的刷新率。这可能吗?我对此做了一些研究,但我发现没有什么真正有用的东西。

我希望我没有错过一些基本的东西。我将不胜感激任何投入。

一个周期的持续时间在 10 到 15 毫秒之间。什么 在此期间,Qt会这样做吗?

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

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

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

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

最新更新