如何在Qt中同步应用程序和监视器的刷新率? [英] How to sync the refresh rate of the application and the monitor in qt?

查看:364
本文介绍了如何在Qt中同步应用程序和监视器的刷新率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wrote a little c++/qt application, that draws a self made cursor on the actual cursor position. To minimize the latency respectively the offset of the actual cursor position and the drawn one, my QWidget updates itself as fast as possible.

构造函数的一部分:

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

paintevent:

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

  1. The duration of the paintevent is about one millisecond. The duration of one cycle is between 10 and 15 milliseconds. What does Qt do in the meantime? Some more information: There's no difference between update() and repaint() and it makes no difference, if i set the timer to a fix integer e.g. Timer->start(2);. The cycle duration goes down by lowering the resolution of the monitor.

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

I'm using a 60 Hz monitor, so i don't really need a higher refresh rate, if i would be able to sync the update with the refresh rate of the monitor. Is that possible? I did a little bit research on that, but i found nothing really helpful.

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

I hope i didn't miss something fundamental. I would be thankful for any input.

推荐答案

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

The duration of one cycle is between 10 and 15 milliseconds. What does Qt do in the meantime?

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

Most likely it sleeps, and/or also tends to other business that the Qt event loop is responsible for. Note that on Windows, the process's timer defaults to a low-resolution mechanism with 10mS granularity (and so if you want your Windows process to be able to sleep for less than 10mS at a time, you'll want to call timeBeginPeriod(1) at the start of your program).

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

sync the update with the refresh rate of the monitor. Is that possible?

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

In principle it is possible, but Qt's QWidget API isn't really designed for that level of control (QWidgets is less of a gaming/multimedia API and more of a classic desktop-application GUI, so it focuses more on getting the content right than on guaranteeing the tightest timing). If you can switch over to using QML instead of the older QWidgets API, QML has some support for syncing-to-monitor-refresh. Another possibility would be to draw your graphics via OpenGL, inside a QOpenGLWindow; the QOpenGLWindow class also has some ability to sync to the refresh rate (see the documentation for its frameSwapped() signal).

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

Btw note that writing output to stdout (a.k.a. std::cout) and/or stderr (a.k.a std::cerr) can by quite slow, and by doing so in your posted program you may be throwing off your timing measurements by a lot. A better approach would be to gather the timing data but just store it inside some sort of data structure until you are done measuring, and then print out the measured values only at the end (e.g. when you quit the program) so that the printing of values doesn't affect the values' accuracy.

这篇关于如何在Qt中同步应用程序和监视器的刷新率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆