Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ TimerEvent在Windows和Mac上具有不同的速度_C++_Qt_Timer_Cross Platform_Qtimer - Fatal编程技术网

C++ TimerEvent在Windows和Mac上具有不同的速度

C++ TimerEvent在Windows和Mac上具有不同的速度,c++,qt,timer,cross-platform,qtimer,C++,Qt,Timer,Cross Platform,Qtimer,我的QT应用程序依赖于TimerEvent(startTimer/killTimer)来创建动画GUI组件。然而,最近我在Mac笔记本电脑上编译并运行了我的应用程序(与我正在开发的Windows桌面电脑相反),发现现在所有东西的运行/更新速度似乎只有平时的一半 应用程序不是滞后的,只是更新率似乎比原来的频率低。我应该怎么做才能保证所有平台上的应用程序的时间一致 或者,我应该为临时计时器事件使用不同的功能吗?我宁愿不这样做,因为TimerEvent对于将更新周期集成到小部件中来说非常方便,但如果它

我的QT应用程序依赖于TimerEvent(startTimer/killTimer)来创建动画GUI组件。然而,最近我在Mac笔记本电脑上编译并运行了我的应用程序(与我正在开发的Windows桌面电脑相反),发现现在所有东西的运行/更新速度似乎只有平时的一半

应用程序不是滞后的,只是更新率似乎比原来的频率低。我应该怎么做才能保证所有平台上的应用程序的时间一致

或者,我应该为临时计时器事件使用不同的功能吗?我宁愿不这样做,因为TimerEvent对于将更新周期集成到小部件中来说非常方便,但如果它们提供一致的计时,我会感兴趣

(上下文的基本示例代码):

//创建MyObject后,计数为20。
//不过,在每个平台上所用的时间明显不同。
类MyObject:公共QObject{
公众:
MyObject(){
timerId=startTimer(60);
}
受保护的:
无效timerEvent(QTimerEvent*事件){

qDebug()由于准确性,您可能会看到问题:

请注意,QTimer的精度取决于底层操作系统和硬件。timerType参数允许您自定义计时器的精度。有关不同计时器类型的信息,请参阅Qt::timerType。大多数平台支持20毫秒的精度;有些平台提供更高的精度。如果Qt无法提供请求的数字,则对于计时器事件,它将悄悄地丢弃一些

您可以尝试将
Qt::PreciseTimer
传递到
startTimer
(默认值为
Qt::roughetimer
),但另外,我建议根据某个开始时间或前一个刻度的时间戳检查当前时间戳。这将允许您调整如何处理计时器事件之间的不同时间量。这与

例如:

class MyObject: public QObject {

public:
  MyObject() {
    timerId = startTimer(60, Qt::PreciseTimer);
    startTime = std::chrono::steady_clock::now();
  }

protected:
  void timerEvent(QTimerEvent* event) {
    qDebug() << (counter++);
    if(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - startTime) / 60 >= 20) {
       killTimer(timerId);
    }
    Object::timerEvent(event);
  }

private:
  int timerId = -1, counter = 0;
  std::chrono::steady_clock::time_point startTime;
}

由于准确性,您可能会看到问题:

请注意,QTimer的精度取决于底层操作系统和硬件。timerType参数允许您自定义计时器的精度。有关不同计时器类型的信息,请参阅Qt::timerType。大多数平台支持20毫秒的精度;有些平台提供更高的精度。如果Qt无法提供请求的数字,则对于计时器事件,它将悄悄地丢弃一些

您可以尝试将
Qt::PreciseTimer
传递到
startTimer
(默认值为
Qt::roughetimer
),但另外,我建议根据某个开始时间或前一个刻度的时间戳检查当前时间戳。这将允许您调整如何处理计时器事件之间的不同时间量。这与

例如:

class MyObject: public QObject {

public:
  MyObject() {
    timerId = startTimer(60, Qt::PreciseTimer);
    startTime = std::chrono::steady_clock::now();
  }

protected:
  void timerEvent(QTimerEvent* event) {
    qDebug() << (counter++);
    if(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - startTime) / 60 >= 20) {
       killTimer(timerId);
    }
    Object::timerEvent(event);
  }

private:
  int timerId = -1, counter = 0;
  std::chrono::steady_clock::time_point startTime;
}

哦,太棒了!那么简单的问题是:使用“startTimer(1,Qt::PreciseTimer)”是否明智然后在所需时间发生更改之前不运行任何TimerEvent内容?我担心性能,因为事件函数会被频繁调用。我最多希望5个小部件同时运行活动计时器事件。对我来说,这似乎是一个过度激进的间隔,除非你真的需要毫秒ond级精度。但这取决于您试图实现的目标。有关计时器分辨率的讨论,请参见eg。他们还指出了一个QeReleastTimer类,该类可能比我的示例解决方案更合适。我的逻辑是,我使用的是“startTimer(5)”对于一些小部件,为了说明Mac上的半速度,我需要将其加倍,可能是“startTimer(2)”?在这种情况下,我最好把它降到1。在这些极端的例子中,计时器只运行约30个周期。其他所有的都是10~15个周期,因此,对于运行时间较长的计时器,5个周期的间隔可能就足够了?(感谢其他建议,将使用QeFalsedTimer)我将测试是否只使用我的建议(
Qt::PreciseTimer
+计算运行时间)在降低轮询时间之前,在实践中为您提供足够好的行为。这可能就足够了。当然,1ms也可以,这取决于它的成本,但我倾向于最小化轮询频率。还请记住,您观察到的情况是“半速”发生的如果Mac上的粗略计时器的精度不够,可能根本不会通过缩短计时器间隔来改变。使用精确计时器可能会完全修复它,但根据观察到的时间步长插入计时器事件的行为是同步跨平台行为的最佳机会。哦,太棒了!那么,快速问一个问题:会吗d简单地使用“startTimer(1,Qt::PreciseTimer)”是明智的然后在所需时间发生更改之前不运行任何TimerEvent内容?我担心性能,因为事件函数会被频繁调用。我最多希望5个小部件同时运行活动计时器事件。对我来说,这似乎是一个过度激进的间隔,除非你真的需要毫秒ond级精度。但这取决于您试图实现的目标。有关计时器分辨率的讨论,请参见eg。他们还指出了一个QeReleastTimer类,该类可能比我的示例解决方案更合适。我的逻辑是,我使用的是“startTimer(5)”对于一些小部件,为了说明Mac上的半速度,我需要将其加倍,可能是“startTimer(2)”?在这种情况下,我最好把它降到1。在这些极端的例子中,计时器只运行约30个周期。其他所有的都是10~15个周期,因此,对于运行时间较长的计时器,5个周期的间隔可能就足够了?(感谢其他建议,将使用QeFalsedTimer)我将测试是否只使用我的建议(
Qt::PreciseTimer
+计算运行时间)提供
class MyObject: public QObject {

public:
  MyObject() {
    timerId = startTimer(60, Qt::PreciseTimer);
    elapsedTimer.start();
  }

protected:
  void timerEvent(QTimerEvent* event) {
    qDebug() << (counter++);
    if(elapsedTimer.elapsed() / 60 >= 20) {
       killTimer(timerId);
    }
    Object::timerEvent(event);
  }

private:
  int timerId = -1, counter = 0;
  QElapsedTimer elapsedTimer;
}