程序运行截图如下:
这里是4个线程,对ListWidget进行输入,
使用MoveToThread,十分简单,但关闭的时候,会出现这样的提示:
造成这样的原因是:
循环还没有结束,线程就被我们关闭了。
解决方法如下:
1.重写关闭事件;
2.使用本地事件循环,先把循环退出后,再退出线程,即可,
程序源码如下:
insertlistitem.h
#ifndef INSERTLISTITEM_H
#define INSERTLISTITEM_H
#include <QObject>
QT_BEGIN_NAMESPACE
class QListWidget;
QT_END_NAMESPACE
class InsertListItem : public QObject
{
Q_OBJECT
public:
explicit InsertListItem(QListWidget *listWidget,QObject *parent = 0);
void stopThread();
public slots:
void beginToWork();
private:
QListWidget *m_listWidget;
bool m_runStatus;
};
#endif // INSERTLISTITEM_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QThread>
class InsertListItem;
class QTimer;
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
private:
Ui::Widget *ui;
InsertListItem *m_list[4];
QThread m_thread[4];
};
#endif // WIDGET_H
insertlistitem.cpp
#include "insertlistitem.h"
#include <QThread>
#include <QListWidget>
#include <QListWidgetItem>
#include <QTime>
#include <QDebug>
InsertListItem::InsertListItem(QListWidget *listWidget, QObject *parent) : QObject(parent)
{
m_listWidget=listWidget;
m_runStatus=true;
}
void InsertListItem::beginToWork()
{
for(int i=0;i<1000;i++){
if(!m_runStatus){
break;
}
QString msg="ThreadId:"
+QString::number((unsigned int)QThread::currentThreadId())
+" "
+" Time:"+QTime::currentTime().toString("HH:mm:ss");
m_listWidget->insertItem(0,msg);
QThread::sleep(1);
}
}
void InsertListItem::stopThread()
{
m_runStatus=false;
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "insertlistitem.h"
#include <QDebug>
#include <QMessageBox>
#include <QCloseEvent>
#include <QEventLoop>
#include <QTimer>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_list[0]=new InsertListItem(ui->listWidget);
m_list[0]->moveToThread(&m_thread[0]);
m_list[1]=new InsertListItem(ui->listWidget_2);
m_list[1]->moveToThread(&m_thread[1]);
m_list[2]=new InsertListItem(ui->listWidget_3);
m_list[2]->moveToThread(&m_thread[2]);
m_list[3]=new InsertListItem(ui->listWidget_4);
m_list[3]->moveToThread(&m_thread[3]);
connect(&m_thread[0],SIGNAL(started()),m_list[0],SLOT(beginToWork()));
m_thread[0].start();
connect(&m_thread[1],SIGNAL(started()),m_list[1],SLOT(beginToWork()));
m_thread[1].start();
connect(&m_thread[2],SIGNAL(started()),m_list[2],SLOT(beginToWork()));
m_thread[2].start();
connect(&m_thread[3],SIGNAL(started()),m_list[3],SLOT(beginToWork()));
m_thread[3].start();
}
Widget::~Widget()
{
delete ui;
}
void Widget::closeEvent(QCloseEvent *event)
{
QMessageBox::StandardButton button=QMessageBox::information(this,"提示","退出",QMessageBox::Ok,QMessageBox::Cancel);
if(button==QMessageBox::Ok){
m_list[0]->stopThread();
m_list[1]->stopThread();
m_list[2]->stopThread();
m_list[3]->stopThread();
QEventLoop loop;
QTimer::singleShot(1*1000,&m_thread[0],SLOT(terminate()));
QTimer::singleShot(1*1000,&m_thread[1],SLOT(terminate()));
QTimer::singleShot(1*1000,&m_thread[2],SLOT(terminate()));
QTimer::singleShot(1*1000,&m_thread[3],SLOT(terminate()));
QTimer::singleShot(1.5*1000,&loop,SLOT(quit()));
QTimer::singleShot(2*1000,this,SLOT(close()));
loop.exec();
event->accept();
}
else{
event->ignore();
}
}