Qt 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制。整个绘图系统基于QPainter,QPaintDevice和QPaintEngine三个类。
QPainter用来执行绘制的操作;QPaintDevice是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间;QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。QPaintEngine类应用于QPainter和QPaintDevice之间,通常对开发人员是透明的。除非你需要自定义一个设备,否则你是不需要关心QPaintEngine这个类的。我们可以把QPainter理解成画笔;把QPaintDevice理解成使用画笔的地方,比如纸张、屏幕等;而对于纸张、屏幕而言,肯定要使用不同的画笔绘制,为了统一使用一种画笔,我们设计了QPaintEngine类,这个类让不同的纸张、屏幕都能使用一种画笔。QPaintEngine一般不用。
上面的示意图告诉我们,Qt 的绘图系统实际上是,使用QPainter在QPainterDevice上进行绘制,它们之间使用QPaintEngine进行通讯(也就是翻译QPainter的指令)。
需要重写paintEvent()事件,此事件在QPaintDevicewindows类下。
//类内声明
//添加画图事件
//在类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下。
//函数实现部分
//实现抗锯齿的能力
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"));
//使用按钮来实现对图片位置的更新,并且当图片到达边界时,图片重新充另一边边界出现。
//函数实现
//点击移动按钮,图片会移动
//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"));
}
绘图设备是指继承QPainterDevice的子类。Qt一共提供了四个这样的类,分别是QPixmap、QBitmap、QImage和 QPicture。其中,
QPixmap继承了QPaintDevice,因此,你可以使用QPainter直接在上面绘制图形。QPixmap也可以接受一个字符串作为一个文件的路径来显示这个文件,比如你想在程序之中打开png、jpeg之类的文件,就可以使用 QPixmap。使用QPainter的drawPixmap()函数可以把这个文件绘制到一个QLabel、QPushButton或者其他的设备上面。QPixmap是针对屏幕进行特殊优化的,因此,它与实际的底层显示设备息息相关。注意,这里说的显示设备并不是硬件,而是操作系统提供的原生的绘图引擎。所以,在不同的操作系统平台下,QPixmap的显示可能会有所差别。
//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绘图设备 与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对象可以进行像素级别的操作。
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是一个可以记录和重现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()命令终止。
//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类的图片
//重现pic的绘图指令
QPicture pic;
pic.load("D:\\pic.ld"); //加载绘图指令
QPainter painter(this);
painter.drawPicture(100,100,pic); //绘图加载绘图指令