多线程绘图
前面见过Image绘图设备可以运用在线程中。
本例子。在线程中随机画出一个多边形,通过信号将图片发出,在主线程中接受该图片,并在绘图事件中绘制。
在窗口中有一个按钮,当点击按钮之后,在线程中绘制一张图片,然后将绘制好的图片显示到当前窗口中。
子线程随机画图解析
class MyThread : public QObject
{
void DrawImage(); //自拟线程处理函数
signals:
void updateImage(QImage temp); //自拟信号
}
//实现线程处理函数
void MyThread::DrawImage()
{
//定义iamge绘图设备
QImage image(400,400,QImage::Format_ARGB32);
//定义画家,指定绘图设备
QPainter p(&image);
//定义画笔
QPen pen;
pen.setWidth(5); //画笔粗细
pen.setStyle(Qt::SolidLine);//画笔样式
//将画笔交给画家
p.setPen(pen);
//定义画刷
QBrush brush;
brush.setStyle(Qt::SolidPattern);//画刷样式
brush.setColor(Qt::red); //画刷颜色
//将画刷交给画家
p.setBrush(brush);
//随机生成5个点,组成一个多边形
QPoint arr[]=
{
QPoint(qrand()%400,qrand()%400),
QPoint(qrand()%400,qrand()%400),
QPoint(qrand()%400,qrand()%400),
QPoint(qrand()%400,qrand()%400),
QPoint(qrand()%400,qrand()%400)
};
//画多边形
p.drawPolygon(arr,5);
//发出信号,并将图片发出
emit updateImage(image);
}
主线程接受图片,并绘制图片解析
//按下按钮,调用线程的线程处理函数
connect(ui->pushButton,&QPushButton::pressed,m_myThread,&MyThread::DrawImage);
//接受信号,取出图片
connect(m_myThread,&MyThread::updateImage,this,&Widget::GetImage);
void Widget::GetImage(QImage temp)
{
m_image=temp; //取出图片
update(); //更新
}
void Widget::paintEvent(QPaintEvent *)
{
//绘图
QPainter p(this);
p.drawImage(100,100,m_image);
}
源代码:
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QImage>
class MyThread : public QObject
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void DrawImage(); //自拟线程处理函数
signals:
void updateImage(QImage temp); //自拟信号
public slots:
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QPainter>
#include <QPen>
#include <QBrush>
MyThread::MyThread(QObject *parent) :
QObject(parent)
{
}
//实现线程处理函数
void MyThread::DrawImage()
{
//定义iamge绘图设备
QImage image(400,400,QImage::Format_ARGB32);
//定义画家,指定绘图设备
QPainter p(&image);
//定义画笔
QPen pen;
pen.setWidth(5); //画笔粗细
pen.setStyle(Qt::SolidLine);//画笔样式
//将画笔交给画家
p.setPen(pen);
//定义画刷
QBrush brush;
brush.setStyle(Qt::SolidPattern);//画刷样式
brush.setColor(Qt::red); //画刷颜色
//将画刷交给画家
p.setBrush(brush);
//随机生成5个点,组成一个多边形
QPoint arr[]=
{
QPoint(qrand()%400,qrand()%400),
QPoint(qrand()%400,qrand()%400),
QPoint(qrand()%400,qrand()%400),
QPoint(qrand()%400,qrand()%400),
QPoint(qrand()%400,qrand()%400)
};
//画多边形
p.drawPolygon(arr,5);
//发出信号,并将图片发出
emit updateImage(image);
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "mythread.h"
#include <QPaintEvent>
#include <QThread>
#include <QImage>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void paintEvent(QPaintEvent *); //绘图事件
public slots:
void GetImage(QImage temp); //通过信号取出图片
signals:
void startDraw();
private:
Ui::Widget *ui;
MyThread *m_myThread; //自定义线程对象
QThread *m_thread; //子线程
QImage m_image; //图片
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->resize(600,600);
//自定义类对象,不可以指定父对象
m_myThread=new MyThread;
//创建子线程
m_thread=new QThread(this);
//将自定义模块附加到子线程
m_myThread->moveToThread(m_thread);
//方式二:用按钮来启动线程,再发出信号,来调用线程处理函数
// connect(ui->pushButton,&QPushButton::pressed,
// [=]()
// {
// m_thread->start();
// emit startDraw();
// }
// );
//connect(this,&Widget::startDraw,m_myThread,&MyThread::DrawImage);
//启动线程,但不启动线程处理函数
m_thread->start();
//按下按钮,调用线程的线程处理函数
connect(ui->pushButton,&QPushButton::pressed,m_myThread,&MyThread::DrawImage);
//接受信号,取出图片
connect(m_myThread,&MyThread::updateImage,this,&Widget::GetImage);
}
Widget::~Widget()
{
delete ui;
}
void Widget::GetImage(QImage temp)
{
m_image=temp; //取出图片
update(); //更新
}
void Widget::paintEvent(QPaintEvent *)
{
//绘图
QPainter p(this);
p.drawImage(100,100,m_image);
}