QTimer 不触发(触发)超时

Posted

技术标签:

【中文标题】QTimer 不触发(触发)超时【英文标题】:QTimer does not fire (trigger) timeout 【发布时间】:2015-09-25 04:08:42 【问题描述】:

我想使用 Qtimer 来暂停执行给定的代码块,而在另一个线程中它会执行其他操作。我用 qeventloop quit 连接了线程的超时,但问题是,没有调用超时。当另一个发射发生时,超时被神奇地触发,或者如果我添加另一个连接,超时也会被触发。我想我错过了关于使用 qtimer、qeventloop 和 qthread 的一些东西。任何人都可以帮忙吗?我把测试的基本代码提取出来放在这里:

main.cpp

#include "widget.h"
#include <QApplication>
#include "tim.h"
#include <QThread>
int main(int argc, char *argv[])

QApplication a(argc, argv);
Widget *w=new Widget();
tim *t=new tim();
QThread *thread=new QThread();
t->moveToThread(thread);
thread->start();
        QThread::connect(w,SIGNAL(signalDoIt()),t,SLOT(slotDoIt()),Qt::QueuedConnection);
QThread::connect(w,SIGNAL(signalQuitTimer()),t,SLOT(slotQuitTimer()),Qt::QueuedConnection);
    QThread::connect(t,SIGNAL(signalSetText(QString)),w,SLOT(slotSetText(QString)),Qt::QueuedConnection);
w->show();
return a.exec();

tim.h

#ifndef TIM_H
#define TIM_H

#include <QObject>
#include<QTimer>
#include<QTime>
#include<QEventLoop>
#include<QThread>
#include<QDebug>
class tim : public QObject

Q_OBJECT
public:
tim();
~tim();
signals:
void signalSetText(QString);
public slots:
void slotDoIt();
void slotQuitTimer();
void slotShowTime();
private:
QTimer *trainingTimer;
QEventLoop loopTrainingWait;
QTime time;
;

#endif // TIM_H

tim.cpp

#include "tim.h"

tim::tim()

qDebug()<<"constructor";
trainingTimer=new QTimer(this);
trainingTimer->setTimerType(Qt::PreciseTimer);
trainingTimer->setSingleShot(true);
QThread::connect(trainingTimer,SIGNAL(timeout()),&loopTrainingWait,SLOT(quit()));
// QThread::connect(trainingTimer,SIGNAL(timeout()),this,SLOT(slotShowTime())); //to uncomment all works, but withou this, it does not

void tim::slotDoIt()


trainingTimer->start(5000);
time.start();
loopTrainingWait.exec();
QString text(QString::number(loopTrainingWait.isRunning())+"  "+ QString::number(time.elapsed()));
qDebug()<<text;
emit signalSetText(text);


void tim::slotShowTime()

QString text(QString::number(loopTrainingWait.isRunning())+" slot "+     QString::number(time.elapsed()));
qDebug()<<text;
emit signalSetText(text);

void tim::slotQuitTimer()

if(loopTrainingWait.isRunning())
    loopTrainingWait.quit();
if(trainingTimer->isActive())
    trainingTimer->stop();

tim::~tim()



//用于测试的gui 小部件.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui 
class Widget;


class Widget : public QWidget

Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();
public slots:
void slotSetText(QString text);
signals:
void signalDoIt();
void signalQuitTimer();
private slots:
void on_pushButton_clicked();

void on_pushButton_2_clicked();

void on_pushButton_3_clicked();

private:
Ui::Widget *ui;
;

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)

ui->setupUi(this);

void Widget::slotSetText(QString text)

ui->label->setText(text);

Widget::~Widget()

delete ui;


void Widget::on_pushButton_clicked()

this->close();


void Widget::on_pushButton_2_clicked()

emit signalDoIt();


void Widget::on_pushButton_3_clicked()

emit signalQuitTimer();

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,最后我在public:之间写了SLOT,然后就可以了

【讨论】:

【参考方案2】:

问题出在静态 qeventloop 中,使这个动态变化

loopTrainingWait=new QEventLoop(this);

与父母一起,解决了这个问题

【讨论】:

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

QTimer::SingleShot 在对象被删除后触发

QTimer没有在线程中触发

QTimer timeout() 方法在代码重组后不再触发

QTimer 超时信号不发出

QT中的Qtimer 里start(100)开始计时以后,timeout是只触发一次,还是说每到100ms就触发一次??

Qt中使用定时器(可使用QObject::timerEvent定时执行,QTimer::singleShot可只触发一次)