最近在看安晓辉老师的《Qt on android核心编程》一书,看到安老师写的一个跨线程使用信号槽的例子很好,特此分享一下,若有其他问题,请联系我删除。邮箱:lsylovecq@qq.com
直接上代码:widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLabel>
#include <QThread>
#include <QPointer>
class SecondFirer : public QObject
{
Q_OBJECT
public:
SecondFirer(int seconds) : m_nSeconds(seconds){}
signals:
void secondLeft(int sec, unsigned int id);
public slots:
void onTimeout();
private:
int m_nSeconds;
};
class CountThread : public QThread
{
public:
CountThread(QWidget * receiver);
~CountThread();
protected:
void run();
private:
QPointer<QWidget> m_receiver;
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
public slots:
void onSecondLeft(int sec, unsigned int id);
private:
QLabel * m_label;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QVBoxLayout>
#include <QMessageBox>
#include <QTimer>
#include <QDebug>
void SecondFirer::onTimeout()
{
if(m_nSeconds >= 0)
{
unsigned int id = (unsigned int)QThread::currentThreadId();
emit secondLeft(m_nSeconds, id);
--m_nSeconds;
qDebug() << "fire secondLeft signal";
}
else
{
QThread::currentThread()->exit(0);
}
}
CountThread::CountThread(QWidget *receiver) : m_receiver(receiver)
{
}
CountThread::~CountThread()
{
qDebug() << "~CountThread";
}
void CountThread::run()
{
qDebug() << "CountThread id - " << (unsigned int)QThread::currentThreadId();
QTimer timer;
SecondFirer firer(10);
connect(&timer, SIGNAL(timeout()), &firer, SLOT(onTimeout()));
timer.start(1000);
if(!m_receiver.isNull())
{
qDebug() << "connect firer && receiver";
connect(&firer, SIGNAL(secondLeft(int,uint)), m_receiver.data(), SLOT(onSecondLeft(int,uint)));
}
exec();
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
, m_label(new QLabel)
{
QVBoxLayout * layout = new QVBoxLayout;
layout->addWidget(m_label);
setLayout(layout);
CountThread * t = new CountThread(this);
connect(t, SIGNAL(finished()), t, SLOT(deleteLater()));
t->start();
}
Widget::~Widget()
{
}
void Widget::onSecondLeft(int iLeft, unsigned int id)
{
QString str = QString("remain %1, current thread id %2, fire thread id %3").arg(iLeft)
.arg((unsigned int)QThread::currentThreadId()).arg(id);
m_label->setText(str);
if(iLeft == 0)
{
QMessageBox::information(this, "CLAP NOW", "It\'s time to clap now!\nClap! Clap! Clap!");
}
}
此处我就不做任何讲解了,代码的优雅之处各位看官自己慢慢体会吧。