Qt定时器问题

时间:2021-10-23 23:27:06
我写了个程序,定义了一个QTimer *timer用来定时,每0.1秒从摄像头捕获一帧。
现在问题是我是从控制台通过命令打开程序,我希望程序运行时,输入“stop”来结束程序,但是程序等待输入时,定时器是不工作的,视频捕获停止。
请问如何解决,视频捕获正常进行,在控制台输入停止命令就程序结束?


ps:我使用了多线程,但是timer->moveToThread(timerThread)时有问题,查询资料也没有解决方案。

5 个解决方案

#1


你可以换个思路,线程里等待标准输入。

#2


你的线程里没必要用QTimer啊,直接用while循环的sleep函数就能解决

#3


我觉得你直接把Qtimer的timeout信号和抓图的那个connect直接断掉就可以啦.

#4


是这样的,这是一个多线程实现中典型的错误使用方式,你发现你的子线程timer定义的signal-slot失效了。看帮助中的这一段:
It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). This means that all of QThread's queued slots will execute in the old thread.  Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.
这里所谓的worker-object approach就是这段文字上边提到的例子:
class WorkerThread : public QThread
{
    Q_OBJECT
    void run() Q_DECL_OVERRIDE {
        QString result;
        /* expensive or blocking operation  */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &s);
};

void MyObject::startWorkInAThread()
{
    WorkerThread *workerThread = new WorkerThread(this);
    connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->start();
}


另外一个变通方式:你把整个thread moveToThread(this); 这里this就是thread对象。这样,你的timer也在子线程中,然后:run里边invoke exec(); 然后在timerEvent里做子线程要做的事情,如果run里没有exec那么就没有eventloop,没有event loop你会发现跨线程的signal-slot竟然不触发了。因为内部实现里还是用到了postEvent

#5


使用线程解决。

#1


你可以换个思路,线程里等待标准输入。

#2


你的线程里没必要用QTimer啊,直接用while循环的sleep函数就能解决

#3


我觉得你直接把Qtimer的timeout信号和抓图的那个connect直接断掉就可以啦.

#4


是这样的,这是一个多线程实现中典型的错误使用方式,你发现你的子线程timer定义的signal-slot失效了。看帮助中的这一段:
It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). This means that all of QThread's queued slots will execute in the old thread.  Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.
这里所谓的worker-object approach就是这段文字上边提到的例子:
class WorkerThread : public QThread
{
    Q_OBJECT
    void run() Q_DECL_OVERRIDE {
        QString result;
        /* expensive or blocking operation  */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &s);
};

void MyObject::startWorkInAThread()
{
    WorkerThread *workerThread = new WorkerThread(this);
    connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->start();
}


另外一个变通方式:你把整个thread moveToThread(this); 这里this就是thread对象。这样,你的timer也在子线程中,然后:run里边invoke exec(); 然后在timerEvent里做子线程要做的事情,如果run里没有exec那么就没有eventloop,没有event loop你会发现跨线程的signal-slot竟然不触发了。因为内部实现里还是用到了postEvent

#5


使用线程解决。