【问题标题】:Exact delay in screen draw and keyboard keypress event in QtQt中屏幕绘制和键盘按键事件的确切延迟
【发布时间】:2014-07-31 05:43:56
【问题描述】:

我正在从事一个 Qt 项目,其中某些事件发生的确切时间是最重要的。具体来说:我有一个非常简单的动画,必须在特定时间绘制到屏幕上,比如 t1。一旦我发出 QWidget 更新以启动动画,将需要一小段时间 dt(取决于屏幕刷新率等)才能在屏幕上实际显示更新。我需要测量这个额外的时间 dt。我不确定该怎么做。

我曾想过在QWidget 的绘制事件中使用QTimeQElapsedTimer 对象,但我不确定这是否能实现我的目标。

类似地,当用户按下一个键时,它会根据键盘的轮询率在一个小的延迟后被注册。我还需要考虑这种延迟。如果我能得到投票率,我知道平均会有多少延迟。

【问题讨论】:

    标签: c++ qt graphics real-time time-precision


    【解决方案1】:

    我曾想过在QWidget 的绘制事件中使用QTimeQElapsedTimer 对象,但我不确定这是否能实现我的目标。

    事实上,这是实现它的唯一方法,也是您真正能做的一切。如果不求助于实时操作系统、自定义驱动程序或外部硬件,将无法做任何进一步的事情。

    您可能不需要两者 - QElapsedTimer 测量自上次更新以来经过的时间就足够了。

    请注意,当事件循环为空时,调用 widget.update() 和执行 paintEvent 之间的延迟不到一微秒,前提是您的进程没有被抢占。

    这是一些研究的反应时间实验。呈现视觉输入,用户通过键盘或鼠标对其做出响应。为了能够准确地找到反应时间,我需要知道刺激是什么时候出现在屏幕上的,什么时候按下了键。

    本质上只有一种方法可以在不借助实时操作系统或自定义驱动程序的情况下正确执行此操作,而错误操作的方法有很多。那么,正确的方法是什么?

    屏幕的一小部分区域需要随着视觉刺激的呈现同时改变颜色或亮度。您将光纤连接到屏幕上,并将其馈送到连接到external event timer 的接收器中。键盘中的触点闭合也馈送到相同的事件计时器。这使您可以精确地计时响应的延迟,而无需考虑操作系统延迟、线程抢占等。如果您愿意做更多的开发工作,事件计时器可以像Arduino 一样便宜。

    如果您重复显示刺激并且需要在刺激呈现之间有一定的时间间隔,您只需经常重复演示并在数据中收集响应延迟和刺激到刺激的时间。然后,您可以丢弃超出所需容差的演示文稿。

    这种方法与屏幕无关,您甚至可以在移动设备上使用它,只要它能够以某种方式与您的计时器硬件交互即可。定时器硬件当然可以联网,使接口变得容易。

    【讨论】:

      【解决方案2】:

      您所要求的是——根据定义——在计算机中是不可能的。

      如果没有将传感器固定在显示器上并与计算机也可以访问的原子钟同步,您希望如何判断像素何时“实际显示”在屏幕上? :-)

      Qt 的胜算更大,因为它通常用作 Win/OSX/Linux 之上的抽象层。那些一开始就不是Real-Time Operating Systems

      您所知道的只是您要求某事发生的时间。然后,您可以计算重新获得控制权以提出另一个请求所需的时间。通过这样做,您可以对您的基本“帧速率”吞吐量设置一些期望值,但有无数因素可能随时导致性能出现巨大差异。

      如果您可以深入了解内核/驱动程序级别,您可以找到一个更接近金属的衡量标准,即实际影响何时到达硬件。但这不是 Qt 的领域,仍然没有告诉你效果何时在外界显现的“实际”答案。

      关于您将从 Qt 中获得的最佳结果是periodic QTimer。它可以(大约)毫秒分辨率进行回调。如果这还不够好……您将需要一艘较小的船。 :-)

      您可能会从与搜索词 "high resolution timer" 相关的内容中获得一点提升:

      【讨论】:

      • 感谢 cmets。是的,毫秒精度很好。我知道还有一个额外的抽象层 - 所以当我在 QWidget 的绘画事件中时,将在绘画开始和绘画函数结束时运行一个高分辨率计时器,给出时间的大致估计花费在将数据推送到屏幕上。如果我理解正确,paint 命令并不总是得到尊重,我该怎么办?
      • @user3726066 我的意思是,您对将数据推送到屏幕上的估计时间的理解——实际上——实际上来自相反的情况:开始计时器在一个paint调用的结束,然后在下一个开始时end。如果您尝试将一堆事件串联起来,您可以对您所说的要查找的数量进行排序。否则你只是在计时你的绘画代码。但此外:如果您解释 为什么 您不能只设置一个周期性的 QTimer 并让它运行,那么解决您的问题会更容易。什么是你不想发生的“坏事”?
      • 好的,知道了。让我解释一下手头的任务,它可以解释为什么我有这样的要求。基本上它是一些研究的反应时间实验。呈现视觉输入,用户通过键盘或鼠标对其做出响应。为了能够准确地找到反应时间,我需要知道刺激是什么时候出现在屏幕上的,什么时候按键是被按下的。由于显示器刷新率非常慢(60Hz),因此在屏幕上绘制的延迟是一个更大的问题。如果您有一些见解,请告诉我...谢谢..
      • 好吧,如果它是学术性的,我会阅读其他人在做什么——你的关键字“屏幕刷新”和“键盘轮询”结合“反应时间实验”或“认知”出现了一些东西比如this PDFthis one。如果你想认真一点,你可以启动一个在 x86 上运行的免费 RTOS,用仪器对其计时一次,然后将计时硬编码到...
      猜你喜欢
      • 1970-01-01
      • 2013-07-03
      • 1970-01-01
      • 2014-06-07
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多