QObject::killTimer: timers cannot be stopped from another thread
产生原因
1 定时器的事件处理所处的线程和调用定时器操作(方法)的线程不是同一个线程。 2 可以通过 qDebug() << QThread::currentThreadId()打印操作时的线程ID。
解决思路
把定时器的操作(方法:start(), stop())))和事件处理放在同一线程内操作。
解决方法
使用connect(ui->pushButton, SIGNAL(clicked()), w, SLOT(SlotShow()));而不是直接使用w->SlotShow();。
关键代码
1 //mainwindow.cpp 2 #include "mainwindow.h" 3 #include "ui_mainwindow.h" 4 #include <QThread> 5 #include <work.h> 6 #include <QDebug> 7 8 MainWindow::MainWindow(QWidget *parent) 9 : QMainWindow(parent) 10 , ui(new Ui::MainWindow) 11 { 12 ui->setupUi(this); 13 w = new Work(); //这里不能指定父对象,如果指定了父对象,moveToThread将无法移动w对象内成员所属的线程。 14 t = new QThread(this); 15 w->moveToThread(t); //这里会把对象w及其w中的成员移动到线程t中(在这之前w中的成员属于主线程)。 16 connect(ui->pushButton, SIGNAL(clicked()), w, SLOT(SlotShow())); //正确用法 17 t->start(); 18 qDebug() << QThread::currentThreadId() << "MainWindow"; 19 } 20 21 MainWindow::~MainWindow() 22 { 23 t->quit(); 24 t->wait(); 25 t->deleteLater(); //这里由于对象t所维护的线程和主线程不属于同一线程,应该使用deleterLater进行释放。 26 delete ui; 27 } 28 29 void MainWindow::on_pushButton_2_clicked() 30 { 31 // w->SlotShow();//错误用法 32 }
1 //work.cpp 2 #include "work.h" 3 #include <QDebug> 4 #include <QThread> 5 #include <QTimer> 6 7 Work::Work(QObject *parent) : 8 QObject(parent) 9 { 10 qDebug() << QThread::currentThreadId() << "Work"; 11 m_t = new QTimer(this); 12 m_t->start(); 13 } 14 15 Work::~Work() 16 { 17 m_t->deleteLater(); 18 } 19 20 void Work::SlotShow() 21 { 22 std::this_thread::sleep_for(std::chrono::seconds(5)); 23 m_t->stop(); 24 qDebug() << QThread::currentThreadId() << "SlotShow"; 25 }
标签:Qt,thread,Work,QObject,线程,ui,include,SlotShow From: https://www.cnblogs.com/ybqjymy/p/18072783