QT 绘图事件

绘图事件

Qt 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制。整个绘图系统基于QPainter,QPaintDevice和QPaintEngine三个类。
QPainter用来执行绘制的操作;QPaintDevice是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间;QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。QPaintEngine类应用于QPainter和QPaintDevice之间,通常对开发人员是透明的。除非你需要自定义一个设备,否则你是不需要关心QPaintEngine这个类的。我们可以把QPainter理解成画笔;把QPaintDevice理解成使用画笔的地方,比如纸张、屏幕等;而对于纸张、屏幕而言,肯定要使用不同的画笔绘制,为了统一使用一种画笔,我们设计了QPaintEngine类,这个类让不同的纸张、屏幕都能使用一种画笔。QPaintEngine一般不用。
在这里插入图片描述
上面的示意图告诉我们,Qt 的绘图系统实际上是,使用QPainter在QPainterDevice上进行绘制,它们之间使用QPaintEngine进行通讯(也就是翻译QPainter的指令)。

QPainter

画图的基本操作

需要重写paintEvent()事件,此事件在QPaintDevicewindows类下。

  1. 需要先创建一个画家对象,即使用QPainter的构造函数,构造函数的参数是所画设备的对象。使用画家调用画图或者写字函数,即可完成画图过程。
  2. 可以更换画笔风格。例如创建画笔对象QPen对象的构造函数,设置笔的宽度setWidth,设置画笔风格setStyle。设置完画笔的各种参数,需要让画家使用画笔,即画家调用setPen()函数。
  3. 还可以设置画刷,画刷其实就是对封闭的图形的填充。使用QBrush构造函数构造画刷对象,设置画刷的风格setStyle(),需要让画家使用画刷,即画家调用setBrush()。
  4. 画各种形状。如,画家调用画线函数drawLine(),画家调用画椭圆函数drawEllipse(),画家调用画矩形函数drawRect(),画家调用写字函数drawText()。
//类内声明
//添加画图事件
//在类QPaintDeviceWindows下
void paintEvent(QPaintEvent *event);

//类外实现
void Widget:: paintEvent(QPaintEvent *event)
{
//*********************画图的基本操作**************************************
    //实例化一个画家,this指定的是绘图的设备,利用画家进行一个操作
    QPainter painter(this);
    //设置笔的颜色
    QPen pen(QColor(255,0,0));
    //设置画笔宽度
    pen.setWidth(3);
    //设置画笔风格
    pen.setStyle(Qt::DashLine);
    //让画家使用这个画笔
    painter.setPen(pen);   //笔要在画的动作之前

    //设置画刷
    QBrush brush(Qt::cyan);
    //设置画刷风格
    brush.setStyle(Qt::BDiagPattern);
    //画家使用画刷
    painter.setBrush(brush);


    //画线
    painter.drawLine(QPoint(0,0),QPoint(100,100));
    //画椭圆,长轴等于纵轴时,是圆
    painter.drawEllipse(QPoint(100,100),100,50);
    //画矩形
    painter.drawRect(QRect(20,20,50,50));       //Rect参数分别是左顶点横纵、坐标、矩形长、宽

    //写字
    painter.drawText(QRect(10,200,100,50),"好好学习,天天向上");
}

画图的高级操作

还是需要重写paintEvent事件,在类QPaintDeviceWindows下。

  1. 首先创建一个画家对象,使用QPainter类的构造函数
  2. 设置一些特殊的画图属性
  • 设置抗锯齿能力,使用函数setRenderHint(),抗锯齿能力提高会使图像更精细,但是会使执行的效率变低。
  • 保存画家状态,便于下一个时刻重新加载,恢复的保存的状态。QPainter调用方法save()和restore()函数实现保存和恢复状态。
  • 利用画家画资源图片,需要先将图片加载到QT资源中,QT中的图片使用的是pixmap。画家使用drawPixmap()方法来实现画图片资源
//函数实现部分
//实现抗锯齿的能力
    painter.drawEllipse(QPoint(100,50),50,50);
    //设置 抗锯齿能力,抗锯齿能力效率会比较低,但是会更精细
    painter.setRenderHint(QPainter::Antialiasing);
    painter.drawEllipse(QPoint(200,50),50,50);
//实现画家状态的保存和加载
    painter.drawRect(QRect(20,20,50,50));
    painter.translate(100,0);           //设置一个偏移
    //保存画家状态
    painter.save();

    painter.drawRect(QRect(20,20,50,50));
    painter.translate(100,0);           //设置一个偏移
    //还原画家保存状态
//    painter.restore();
    painter.drawRect(QRect(20,20,50,50));

//画图片资源
 painter.drawPixmap(this->posx,0,QPixmap(":/Luffy.png"));
  1. paintEvent()函数的重新调用,在使用update()函数,重新实现一次paintEvent()。
//使用按钮来实现对图片位置的更新,并且当图片到达边界时,图片重新充另一边边界出现。
//函数实现
//点击移动按钮,图片会移动
//posx是类的一个属性,代表的也就是一个横坐标位置
connect(ui->pushButton,&QPushButton::clicked,[=]()
{
    this->posx += 20;
    //如果手动调用绘图事件,用update来更新
    update();
});

paintEvent()
{
    if(posx>this->width())          //width获取屏幕宽度
    {
        posx = 0;
    }
    painter.drawPixmap(this->posx,0,QPixmap(":/Luffy.png"));
}

QPaintDevice

绘图设备是指继承QPainterDevice的子类。Qt一共提供了四个这样的类,分别是QPixmap、QBitmap、QImage和 QPicture。其中,

  • QPixmap专门为图像在屏幕上的显示做了优化
  • QBitmap是QPixmap的一个子类,它的色深限定为1,可以使用 QPixmap的isQBitmap()函数来确定这个QPixmap是不是一个QBitmap。
  • QImage专门为图像的像素级访问做了优化。
  • QPicture则可以记录和重现QPainter的各条命令。

QPixmap

QPixmap继承了QPaintDevice,因此,你可以使用QPainter直接在上面绘制图形。QPixmap也可以接受一个字符串作为一个文件的路径来显示这个文件,比如你想在程序之中打开png、jpeg之类的文件,就可以使用 QPixmap。使用QPainter的drawPixmap()函数可以把这个文件绘制到一个QLabel、QPushButton或者其他的设备上面。QPixmap是针对屏幕进行特殊优化的,因此,它与实际的底层显示设备息息相关。注意,这里说的显示设备并不是硬件,而是操作系统提供的原生的绘图引擎。所以,在不同的操作系统平台下,QPixmap的显示可能会有所差别。

  1. 创建绘图设备QPixmap对象
  2. 设置绘图设备QPixmap对象的属性,例如填充颜色
  3. 创建画家对象QPainter对象,以所创建的QPixmap对象为绘图空间
  4. 进行一些属性的设置,如画笔QPen、画刷QBrush
  5. 进行绘画
  6. 保存图片,用save方法。QPixmap对象的save方法与QPainter的save方法不同,此方法是保存文件到磁盘中,QPainter的save方法是保存画家的状态,需要使用restore放法来恢复状态。
//Pximap绘图设备,可以保存到磁盘,专门为平台做了显示的优化
QPixmap pix(300,300);       //设定宽和高

//填充颜色,这里是设置的整个背景的颜色
pix.fill(Qt::blue);
//声明画家
QPainter painter(&pix);     //参数为所画地址
//设置画笔
painter.setPen(QPen(Qt::green));
painter.drawEllipse(QPoint(150,105),100,100);   //画一个椭圆
//保存到D盘
pix.save("D:\\pxi.png");

QImage

QImage使用独立于硬件的绘制系统,实际上是自己绘制自己,因此提供了像素级别的操作,并且能够在不同系统之上提供一个一致的显示形式。也就是说QImage能进行像素级别的操作。

  1. 创建绘图设备QImage对象
  2. 设置绘图设备QImage对象的属性,例如填充颜色
  3. 创建画家对象QPainter对象,以所创建的QImage对象为绘图空间
  4. 进行一些属性的设置,如画笔QPen、画刷QBrush
  5. 进行绘画
  6. 保存图片,用save方法。QImage对象的save方法与QPainter的save方法不同,此方法是保存文件到磁盘中,QPainter的save方法是保存画家的状态,需要使用restore放法来恢复状态。
//QImage绘图设备  与QPixmap的流程大致一致,但是多了可以对像素进行操作
QImage img(300,300,QImage::Format_RGB32);       //第三个参数是格式
img.fill(Qt::black);        //填充白色
QPainter painter(&img);
painter.setPen(QPen(Qt::blue));
painter.drawEllipse(QPoint(150,150),100,100);
//保存
img.save("D:\\img.png");

QImage对象可以进行像素级别的操作。

  1. 创建画家对象QPainter
  2. 创建绘图设备QImage
  3. 绘图设备装载图片QImage对象的方法load()加载图片,此时QImage对象这时代表就是一张图片
  4. 使用QImage对象的setPixel设置像素点
  5. 将修改后的QImage图片显示出来
void Widget::paintEvent(QPaintEvent * event)
{
    //创建画家对象
    QPainter painter(this);     //向当前窗口画图
    //利用QImage对象对像素进行修改
    QImage image;
    image.load(":/Luffy.png");    //加载图片
    //修改像素点
    for(int i = 50;i<100;i++)
    {
        for(int j = 0;j<100;j++)
        {
            QRgb value = qRgb(255,0,0);     //创建QRgb对象
            image.setPixel(i,j,value);      //修改像素点的值
        }
    }
}

QPicture

QPicture是一个可以记录和重现QPainter命令的绘图设备。 QPicture将QPainter的命令序列化到一个IO设备,保存为一个平台独立的文件格式。这种格式有时候会是“元文件(meta- files)”。Qt的这种格式是二进制的,不同于某些本地的元文件,Qt的pictures文件没有内容上的限制,只要是能够被QPainter绘制的元素,不论是字体还是pixmap,或者是变换,都可以保存进一个picture中。
QPicture是平台无关的,因此它可以使用在多种设备之上,比如svg、pdf、ps、打印机或者屏幕。回忆下我们这里所说的QPaintDevice,实际上是说可以有QPainter绘制的对象。QPicture使用系统的分辨率,并且可以调整 QPainter来消除不同设备之间的显示差异。
如果我们要记录下QPainter的命令,首先要使用QPainter::begin()函数,将QPicture实例作为参数传递进去,以便告诉系统开始记录,记录完毕后使用QPainter::end()命令终止。

  1. 创建绘图设备QPicture类对象
  2. 创建画家QPainter类对象
  3. 画家调用QPainter类中的方法begin(),绑定函数
  4. 设置画笔、画刷等属性,将属性加载到画家对象上
  5. 调用画家对象的方法end()结束画画
  6. 调用QPicture类的对象的方法save保存图片
//QPicture 绘图设备 可以记录和重现绘图指令
QPicture pic;       //创建绘图设备
QPainter painter;      //创建画家对象
painter.begin(&pic);    //开始画画
painter.setPen(QPen(Qt::blue));  //设置画笔
painter.drawEllipse(QPoint(50,50),50,50);
painter.end();      //结束画画
pic.save("D:\\pic.ld");         //保存的文件中含有所有指令

读取QPicture类的图片

  1. 创建QPicture用来保存图片数据
  2. 使用QPicture类中的方法load()来读取Picture数据
  3. 创建画家类QPainter对象
  4. 画家对象调用drawPicture方法,还原图片
 //重现pic的绘图指令
QPicture pic;
pic.load("D:\\pic.ld");     //加载绘图指令
QPainter painter(this);
painter.drawPicture(100,100,pic);       //绘图加载绘图指令

你可能感兴趣的:(QT,qt)