QTimer 超时信号不发出

Posted

技术标签:

【中文标题】QTimer 超时信号不发出【英文标题】:QTimer timeout signal doesn't emit 【发布时间】:2019-08-01 15:20:44 【问题描述】:

我正在使用 QTimer,但没有发出超时信号。

这是我的代码:

    QTimer* receiveTimer = new QTimer();
    receiveTimer->setInterval(1000);
    connect(receiveTimer, SIGNAL(timeout()), this, SLOT(timeout()));

    QByteArray res;
    inWait = true;
    receiveTimer->start();

    qDebug() << "Before while";

    while (!res.contains("OK\r\n") && inWait)
        qDebug() << res.append(sPort->read(1));

    qDebug() << "After while";

    receiveTimer->stop();

一开始,我在类构造函数中定义了定时器,但也没有用。

【问题讨论】:

QTimer 仅在 Qt 事件循环运行时工作;当您的线程卡在您自己的 while() 循环中时,它不能/不会工作,因为这会阻止 Qt 事件循环执行事件。在此处查看详细信息:***.com/questions/42279360/… 那么,我应该创建另一个线程并在那里启动计时器吗? @JeremyFriesner 不——你应该做的是不要尝试在 while() 循环中阻塞;不能很好地与 Qt 的事件驱动模型集成。即,如果您想在“一段时间后”停止您的 receiveTimer,请在 timeout() 插槽内执行此操作,而不是尝试在您启动计时器的同一功能的底部执行此操作。 摆脱 while 循环。而是在可用时使用信号和插槽来处理数据。基本上这个函数需要在你的类中划分到不同的槽中。 您必须深入了解基于事件的应用程序架构的概念。你永远不会等待自己。框架(来自其事件循环的 Qt)将在发生某些事情时调用您的代码。你对它做出反应,也许设置稍后发生的事情(使用计时器,或者通过发送网络请求,或者通过启动外部进程,或者......),然后尽快返回,因为只要你的代码是正在运行,没有其他代码正在运行。如果你觉得这很困难,那就更努力地思考 :-) 在你真正掌握普通单线程 Qt 应用程序的架构之前忘记线程。 【参考方案1】:

您可以将其添加到您的循环中:

QCoreApplication::processEvents(QEventLoop::AllEvents, 100);

QApplication::processEvents(QEventLoop::AllEvents, 100);

我在 qt 中的“睡眠”功能:

void WebView::delay(int sec)

    QTime dieTime= QTime::currentTime().addSecs(sec);
    while (QTime::currentTime() < dieTime)
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);


如果我理解你的话,你想要的不是这样的:

QByteArray res;

QTime dieTime= QTime::currentTime().addSecs(sec);
while (!res.contains("OK\r\n") && QTime::currentTime() < dieTime) 
    QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    qDebug() << res.append(sPort->read(1));

【讨论】:

其实我希望我的 while 最大限度地运行 1 秒,然后休息。首先我是用计时器来做的,现在我意识到那是行不通的。那么,最好的方法是什么?我阅读了 QEventloop 和 QThread,但没有多大帮助...

以上是关于QTimer 超时信号不发出的主要内容,如果未能解决你的问题,请参考以下文章

QTimer 不触发(触发)超时

QTimer 线程亲和性

如果在连接信号之前调用 Slot,则无法连接到 QTimer Slot 中发送的信号

QTimer:“多次超时”可能吗?

QTimer::singleShot()函数使用

当 singleShot 为 True 时,QTimer 永远不会触发超时 [关闭]