QT学习之线程和定时器

我做了一个读卡工具,有个连续读卡功能,读卡时还得一直寻卡,寻到卡后才能读;为避免死等,可以在连续读卡中去停止读卡,所以需要写一个线程用来读卡;
我使用的是moveToThread方式;
我有个窗口程序,有个读卡类;我希望读卡时是个线程在操作,所以我在窗口上定义了一个线程对象:

//在类中定义一个QThread对象m_thread
QThread m_thread;`

并把读卡器类设置到线程上并启动线程:

    // 启动读卡线程
    readIdCard.moveToThread(&m_thread);
    m_thread.start();

读卡器类中,新增一个定时器,并且设置定时器超时就掉一下读卡接口readCardOnce;

timer = new QTimer(this);
timer->setInterval(500);
connect(timer, SIGNAL(timeout()), this, SLOT(readCardOnce()));

readCardOnce接口:

if(!m_isRead){ // 设此标记是为了能即使停定时器
    traceLogLib.outPutMsg(QtDebugMsg, "ReadIdCard::readerCardOnce invoke end. m_isRead = false");
    return;
}
// 寻卡
。。。省略
if(寻卡成功)
{
// 读取身份证信息
。。。省略
}

窗口和读卡线程是靠信号和槽连接的:思路是信号和槽的关联都在窗口里去设置,因为窗口已经有读卡类了,且窗口的头文件无法在其他文件里引入(QT的限制);如下:做发射读卡信号,那边读卡成功后会发射读卡结果的信号,这边readCardOnceResult进行处理数据即可;

// 开关端口
connect(this, SIGNAL(openAndClose()), &readIdCard, SLOT(openAndClosePort())); // 关联信号和槽
connect(&readIdCard, SIGNAL(openAndCloseResult(int)), this, SLOT(openAndCloseResult(int))); // 处理打开设备结果
// 一次读卡
connect(this, SIGNAL(readCardOnce()), &readIdCard, SLOT(readCardOnce())); // 关联信号和槽
connect(&readIdCard, SIGNAL(readCardOnceResult(int)), this, SLOT(readCardOnceResult(int)));

//连续读卡
connect(this, SIGNAL(readCardTimes()), &readIdCard, SLOT(readCardTimes())); // 关联信号和槽
connect(this, SIGNAL(stopReadCard()), &readIdCard, SLOT(stopReadCard())); // 关联信号和槽
connect(&readIdCard, SIGNAL(stopReadCardResult()), this, SLOT(stopReadCardResult()));

点击开始读卡后,窗口给读卡类发射开始读卡信号,读卡器类的对应接口readCardTimes启动读卡定时器:

timer->start();

正在寻卡时,点了停止读卡,会触发停止读卡信息,由读卡器类的接口stopReadCard进行停止定时器:

if(timer->isActive()){
    traceLogLib.outPutMsg(QtDebugMsg, "暂停定时器。。。");
    timer->stop();
    if (timer->isActive()) {
        traceLogLib.outPutMsg(QtDebugMsg, "暂停定时器成功");
    }
}

窗口点右上角X关掉时,需要停掉线程:
通过重写void closeEvent(QCloseEvent*);实现的:


void QtWidgetsApplication32::closeEvent(QCloseEvent *e)
{
    //窗口关闭时弹出的提示窗口
    QMessageBox msgBox;
    msgBox.setText("提示");
    msgBox.setInformativeText("确认退出?");
    msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
    msgBox.setDefaultButton(QMessageBox::Ok);
    int ret = msgBox.exec();
    if (ret == QMessageBox::Ok) {
        //若用户点击确认,则接收这个事件,当前窗口会关闭
        e->accept();
        m_thread.quit(); // 退出线程
    }
    else {
        //若用户点击取消,则忽略这个事件,当前窗口不会关闭
        e->ignore();
    }
}
  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值