• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

QObject::killTimer: timers cannot be stopped from another thread

武飞扬头像
ChindongX
帮助1

QObject::killTimer: timers cannot be stopped from another thread

产生原因

定时器的事件处理所处的线程和调用定时器操作(方法)的线程不是同一个线程。
可以通过 qDebug() << QThread::currentThreadId()打印操作时的线程ID。

解决思路

把定时器的操作(方法:start(), stop())))和事件处理放在同一线程内操作。

解决方法

使用connect(ui->pushButton, SIGNAL(clicked()), w, SLOT(SlotShow()));而不是直接使用w->SlotShow();

关键代码

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>
#include <work.h>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)
  , ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  w = new Work();	//这里不能指定父对象,如果指定了父对象,moveToThread将无法移动w对象内成员所属的线程。
  t = new QThread(this);
  w->moveToThread(t); //这里会把对象w及其w中的成员移动到线程t中(在这之前w中的成员属于主线程)。
  connect(ui->pushButton, SIGNAL(clicked()), w, SLOT(SlotShow())); //正确用法
  t->start();
  qDebug() << QThread::currentThreadId() << "MainWindow";
}

MainWindow::~MainWindow()
{
  t->quit();
  t->wait();
  t->deleteLater(); //这里由于对象t所维护的线程和主线程不属于同一线程,应该使用deleterLater进行释放。
  delete ui;
}

void MainWindow::on_pushButton_2_clicked()
{
   // w->SlotShow();//错误用法
}
学新通
//work.cpp
#include "work.h"
#include <QDebug>
#include <QThread>
#include <QTimer>

Work::Work(QObject *parent) :
  QObject(parent)
{
  qDebug() << QThread::currentThreadId() << "Work";
  m_t = new QTimer(this);
  m_t->start();
}

Work::~Work()
{
  m_t->deleteLater();
}

void Work::SlotShow()
{
  std::this_thread::sleep_for(std::chrono::seconds(5));
  m_t->stop();
  qDebug() << QThread::currentThreadId() << "SlotShow";
}
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbkicc
系列文章
更多 icon
同类精品
更多 icon
继续加载