How to sync the refresh rate of the application and the monitor in qt?

故事扮演 提交于 2020-04-18 05:46:20

问题


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.

Part of the constructor:

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

}

Now i have two questions:

  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.

  2. 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.


回答1:


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

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?

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).

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.



来源:https://stackoverflow.com/questions/60198978/how-to-sync-the-refresh-rate-of-the-application-and-the-monitor-in-qt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!