1.work.h
#ifndef WORK_H
#define WORK_H
#include <QObject>
#include "QImage"
class Work : public QObject
{
Q_OBJECT
public:
explicit Work(QObject *parent = nullptr);
signals:
void ImageDone(QImage image);
public slots:
void slotDrawImage();
};
#endif // WORK_H
2.work.cpp
#include "work.h"
#include "QPainter"
#include <QtGlobal>
#include "QPoint"
Work::Work(QObject *parent) : QObject(parent)
{
}
void Work::slotDrawImage()
{
QImage image(600,600,QImage::Format_ARGB32);
QPainter painter(&image);
QPoint pt[] =
{
QPoint(qrand()%590, qrand()%590),
QPoint(qrand()%590, qrand()%590),
QPoint(qrand()%590, qrand()%590),
QPoint(qrand()%590, qrand()%590),
QPoint(qrand()%590, qrand()%590),
};
painter.drawPolygon(pt,5);
emit ImageDone(image);
}
3.mywidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
namespace Ui {
class MyWidget;
}
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = nullptr);
~MyWidget();
private:
Ui::MyWidget *ui;
QImage m_image;
protected:
void paintEvent(QPaintEvent *);
};
#endif // MYWIDGET_H
4.mywidget.cpp
#include "mywidget.h"
#include "ui_mywidget.h"
#include "work.h"
#include <QThread>
#include <QPainter>
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyWidget)
{
ui->setupUi(this);
Work* pWork = new Work; //这里不能给pwork指明父对象,不然效果会出错
connect(ui->draw, &QPushButton::clicked,
pWork, &Work::slotDrawImage);
QThread * pthread = new QThread(this);
// 将操作移入子线程中处理
pWork->moveToThread(pthread);
// 启动子线程
pthread->start();
connect(pWork, &Work::ImageDone, [=](QImage image)
{
// 保存图片
m_image = image;
// 刷新窗口
update();
});
connect(this, &MyWidget::destroyed, [=]()
{
// 退出线程
pthread->quit();
pthread->wait();
delete pWork;
});
}
void MyWidget::paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.drawImage(0, 0, m_image);
}
MyWidget::~MyWidget()
{
delete ui;
}
多线程使用注意事项:
1.线程不能操作UI对象(比如从QWidget直接或间接派生的窗口对象)
2.需要移动到子线程中处理的模块类,创建类对象的时候不能指定父对象