在线程中绘图可分为两个步骤,即划分子线程以及在线程中绘图。
创建子线程的过程如下:
首先先建立一个子线程的类,再在主窗口类中定义子线程对象。使用moveToThread方法移动到子线程而不用run进入。 在调用start()开启线程后就可以在子线程中绘制想要的图形创建一个自定义线程类(可以用信号与槽的方式进入线程以及从子线程中输出相应的信息给主线程)。
本次程序主要是完成在窗口点击鼠标从而在点击的点中显示在子线程所绘制的图片。
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this -> resize(1400,850);
pMainThread = new QThread(this);
pChildThread = new Thread;
pChildThread -> moveToThread(pMainThread);
m_x = m_y = 0;//点击的横纵坐标。
pMainThread -> start();//开启线程
connect(this,&Widget::clicked,pChildThread,&Thread::slotDraw);//点击某个位置后,进入子线程绘图
connect(pChildThread,&Thread::signalDrawUp,this,&Widget::ImageGot);//获取子线程绘制的图
connect(this,&Widget::destroyed,this,&Widget::dealDestroyed);//关闭窗口则关闭子线程
}
Widget::~Widget()
{
}
void Widget::paintEvent(QPaintEvent *Event)
{
QPainter painter(this);
painter.drawImage(m_x,m_y,Image,m_x,m_y,256,256);//在点击点绘制Image图
}
void Widget::mousePressEvent(QMouseEvent *e)//鼠标点击事件。
{
this ->m_x = e -> x();
this ->m_y = e -> y();
emit clicked(m_x,m_y);
}
void Widget::ImageGot(QImage m_Img)//获取图片
{
Image = m_Img;//将子线程的图赋给Image
update();//更新图形,间接调用paintEvent()
}
void Widget::dealDestroyed()//窗口关闭,则关闭线程
{
pMainThread ->quit();
pMainThread ->wait();
delete pChildThread;
}
在主窗口中实现了进入子线程,获取子线程的图,显示绘制好的图形,关闭线程的操作。
在子线程中需要做的操作则是绘制相应的图形:
void Thread::slotDraw(int x,int y)
{
QImage Img(1400,850,QImage::Format_ARGB32);//设置绘图设备大小以及格式,
QPainter painter(&Img);
// painter.drawImage(x,y,QImage("C:/Users/MSI-NB/Desktop/test/123.jpg"));
painter.drawImage(x,y,QImage("C:/Users/MSI-NB/Desktop/test/coronavirus-icons-01.png"));
emit signalDrawUp(Img);//绘制完成后发送相应信号。
}