【qt】绘图事件| 绘图设备

举报
xcc-2022 发表于 2022/11/28 18:58:55 2022/11/28
【摘要】 9、绘图事件和绘图设备什么时候画?在显示到屏幕的前一刻画出来,绘图事件可以做到绘图:窗口需要重新显示的时候,就会收到一个绘图事件 paintEvent,我们先体验一个触发绘图事件简单的代码:void Mypushbutton::paintEvent(QPaintEvent *ev){ static int num = 1; qDebug()<<num++; QPushBu...

9、绘图事件和绘图设备

什么时候画?

在显示到屏幕的前一刻画出来,绘图事件可以做到

绘图:窗口需要重新显示的时候,就会收到一个绘图事件 paintEvent,我们先体验一个触发绘图事件简单的代码:

void Mypushbutton::paintEvent(QPaintEvent *ev)
{
    static int num = 1;
    qDebug()<<num++;
    QPushButton::paintEvent(ev);//画出自己
}

我们每次改动后或者移动都会触发绘图事件,收到绘图事件之后,窗口就要将自己画出来;那我们知道了什么时候画,那应该怎么画:

首先需要画画的人QPainter、画笔QPen、画布QPaintDevice

9.1 QPainter

我们写学基本的绘图:

	QPainter ( 参数是绘图设备 ,this表示在窗口上绘图)
			drawLine 划线 , 两点成一线,参数就是两个点的坐标
			drawRect 矩形 , 参数是 左上角的点和 宽和高
			drawEllips 画椭圆 , 参数是 左上角的点和 宽和高  ,另一种方式就是 圆心 + rx + ry
			

	设置画家的画笔
			setPen ( QPen)   ,画笔可以设置颜色和风格
		设置画家的画刷
			setBrush(QBrush) , 填充封闭的图形, 也可以设置颜色 ,默认情况下,画刷不填充,还得设置风格
		搬动画家
			translate ( x, y) 将画家移动到某个坐标开始画画

void paintEvent(QPaintEvent *event) ;

#include<QPainter>
//在这里画画
    QPainter painter(this);//以当前窗口作为图片设备

    //画家偏移,搬动画家到某个坐标上开始画画
    painter.translate(100,0);

    //创建一支画笔
    QPen pen;
    pen.setColor(QColor(255,0,0));
    //设置笔宽
    pen.setWidth(3);
    //设置画笔的风格
    pen.setStyle(Qt::DashLine);

    //画家设置画笔
    painter.setPen(pen);

    //需要填充,使用画刷
    QBrush brush;
    brush.setColor(Qt::cyan);
    //默认情况下,画刷不填充,还得设置风格
    brush.setStyle(Qt::Dense4Pattern);

    //画家设置画刷
    painter.setBrush(brush);
    //画一条线
    painter.drawLine(0,0,100,100);
    //画矩形
    painter.drawRect(20,20,50,50);
    //画圆形,使用椭圆
    painter.drawEllipse(QPoint(100,100),50,50);
    //画文字
    painter.drawText(200,100,"好好学习,天天向上");

我们可以联想现实生活中画画,如果需要更改颜色就要挑选颜色,并重新设置拾取使用;

9.2 手动触发绘图事件

我们用painter绘制已经从存在的图片,需要添加图片资源,

QPainter painter(this);
    QPixmap pixmap(":/image/Sunny.jpg");//图片路径
    painter.drawPixmap(0,0,pixmap);//坐标

我们继续添加一些功能,每次点击一个按键移动一下位置:

需要添加一个按键,并转到槽,在头文件中定义一个mPox变量,并在源文件中初始化为0;设置按键点击事件,按一次,移动10像素

void Widget::on_pushButton_clicked()
{
    //每点击而一次,向右移动图片,10个像素
    mPox += 10;
}

我们发现我们点击按键没有直接移动图片,而是最小化之后在打开,图片才移动了位置;所以我们需要设置手动触发事件

有两种方法:repaint()、update();它们的区别是:repaint会马上触发,在函数中调用了多次repaint,会收到很多次绘图事件;

update做了优化,多次调用update只会触发一次,通常我们用update

注意:不要在paintEvent处理函数中再触发绘图事件,会导致无限循环

9.3 绘图设备

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

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

9.3.1 QPixmap

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

#include<QPainter>
#include<QPixmap>

	QPixmap pix(300,300);//图片宽高
    QPainter painter(&pix);//以图片作为绘图设备
    painter.drawEllipse(QPoint(150,150),100,100);//坐标,半径
    pix.save("D:\\qt\\code\\painterDevice\\pix.png");//保存的位置

我们的关注点不是在运行界面上,我们打开文件后,看到多了一个图片,黑乎乎的,默认是填充黑色颜色,我们设置一下

对比:设置为白色,形状为红色

9.3.2 QImage

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

我们声明了一个QImage对象,大小是300 x 300,颜色模式是RGB32,即使用32位数值表示一个颜色的RGB值,也就是说每种颜色使用8位。然后我们对每个像素进行颜色赋值,从而构成了这个图像。我们可以把QImage想象成一个RGB颜色的二维数组,记录了每一像素的颜色。

我们先显示一张图片,然后再改它的像素

  //修改像素
    for(int x = 50;x<100;x++)
    {
        for(int y = 50;y<100;y++)
        {
            img.setPixelColor(x,y,QColor(255,0,0));
        }
    }

9.3.3 QImage与QPixmap的区别

QPixmap主要是用于绘图,针对屏幕显示而最佳化设计,QImage主要是为图像I/O、图片访问和像素修改而设计的

QPixmap依赖于所在的平台的绘图引擎,故例如反锯齿等一些效果在不同的平台上可能会有不同的显示效果,QImage使用Qt自身的绘图引擎,可在不同平台上具有相同的显示效果

由于QImage是独立于硬件的,也是一种QPaintDevice,因此我们可以在另一个线程中对其进行绘制,而不需要在GUI线程中处理,使用这一方式可以很大幅度提高UI响应速度。

QImage可通过setPixpel()和pixel()等方法直接存取指定的像素。

QImage与QPixmap之间的转换:

QImage转QPixmap

使用QPixmap的静态成员函数: fromImage()

QPixmap fromImage(const QImage & image,   
		Qt::ImageConversionFlags flags = Qt::AutoColor);

QPixmap转QImage:

使用QPixmap类的成员函数: toImage()

QImage toImage() const;

9.3.4 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()命令终止。代码示例如下:

#include<QPicture>
	QPicture pic;
    QPainter painter;
	 //将图像绘制到QPicture中,并保存到文件
    painter.begin(&pic);
    painter.drawEllipse(20, 20, 100, 50);
    painter.fillRect(20, 100, 100, 100, Qt::red);
    painter.end();
    pic.save("D:\\drawing.pic");

	 //将保存的绘图动作重新绘制到设备上
    pic.load("D:\\drawing.pic");
    painter.begin(this);
    painter.drawPicture(200, 200, pic);
    painter.end();
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。