• QTimer掉坑出坑过程


      最近遇到一个问题,就是关于QTimer设置了10ms,结果不生效,很头疼啊,查了快一天了,终于知道为什么了?

      先说下QTimer的使用方法:

      m_delayHideTimer这是QTimer的对象。

    connect(&m_delayHideTimer, SIGNAL(timeout()), this, SLOT(slotHideMenu())); //时间耗尽就会响应后面的回调函数。

     m_delayHideTimer.setInterval(100) //重新设置定时器的时间。

     m_delayHideTimer.stop(); //停掉定时器

     m_delayHideTimer.start(50);//开始定时器

    其他的用法,查看QT asssistant就知道了不多啰嗦 上重点:

      为什么10ms的精度不生效:

       这里说下QT的源码,里面关于定时器的实现:

    在QT的qeventdispatcher_win.cpp 文件里,有个函数具体如下:

    void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t)
    {
    Q_ASSERT(internalHwnd);

    Q_Q(QEventDispatcherWin32);

    int ok = 0;
    calculateNextTimeout(t, qt_msectime());
    uint interval = t->interval;
    if (interval == 0u) {
    // optimization for single-shot-zero-timer
    QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId));
    ok = 1;
    } else if ((interval < 20u || t->timerType == Qt::PreciseTimer) && qtimeSetEvent) {
    ok = t->fastTimerId = qtimeSetEvent(interval, 1, qt_fast_timer_proc, (DWORD_PTR)t,
    TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
    }

    if (ok == 0) {
    // user normal timers for (Very)CoarseTimers, or if no more multimedia timers available
    ok = SetTimer(internalHwnd, t->timerId, interval, 0);
    }

    if (ok == 0)
    qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer");
    }

    源码可知,做了几件事情:如果定时器的精度小于20ms,就会进入 qtimeSetEvent 这个函数,否则去走winapi 中的SetTimer,这个不多说。

    qtimeSetEvent  这个函数的实现是:

    qtimeSetEvent = (ptimeSetEvent)QSystemLibrary::resolve(QLatin1String("winmm"), "timeSetEvent");
    qtimeKillEvent = (ptimeKillEvent)QSystemLibrary::resolve(QLatin1String("winmm"), "timeKillEvent");

    winmm是windows的多媒体应用程序的接口,是个动态库。去响应windows是的多媒体定时器。

    这个定时器如果在精度不是特别高的情况下不要随便的使用,因为win会给这个顶定时器单独分配一个线程,调用几次timeSetEvent,就需要调用几次timeKillEvent ,相对应的ID也要相同。

    查了中外的各种论坛,有说同一个线程不能超过16个 也有说同一个进程不能超过16个 总之 超过16个就不生效的肯定是存在的,这里还是尽量不要写精度小于20Ms的定时器,以防万一。后续有

    这个方面的研究,再更新 先去改bug了。。。

    后续验证: 多媒体定时器一个进程只能开16个!所以这个高精度的定时器还是要慎用!!

  • 相关阅读:
    听说高手都用记事本写C语言代码?真的假的!
    面向监狱编程,就靠它了!日子是越来越有判头了!
    如何把安静的程序员逼成话唠!
    想要自学编程?一个B站远远不够!
    2021年,学习C++还香吗?(文末赠书)!
    JVM--分代收集理论和垃圾收集算法
    Redis面试题
    基于RT1052 Aworks 使能GPIO输入功能(六)
    基于RT1052 Aworks 使能GPIO输出功能(五)
    基于RT1052 Aworks 使能ADC功能(四)
  • 原文地址:https://www.cnblogs.com/132818Creator/p/8574199.html
Copyright © 2020-2023  润新知