第八章绘图
文章目录
Paint System
Qt的绘制系统支持在屏幕和打印设备上使用相同的API进行绘制,主要基于QPainter、QPaintDevice和QPaintEngine类。
基本绘制和填充
QPainter中提供了一些便捷函数来绘制常用的图形,还可以设置线条、边框的画笔以及进行填充的画刷。
所有对控件的绘图操作都要放进函数paintEvent()中,否则无法显示。
绘制图形
QPainter使用
void Widget::paintEvent(QPaintEvent* event)
{
QPainter painter;
painter.begin(this);
QPoint pos[4] = { { 10, 10 }, { 20, 20 }, { 300, 10 }, { 20, 400 } };
painter.drawLines(pos, 4);
painter.end(); // 调用了begin就要调用end,释放资源
}
也可以这样用
void Widget::paintEvent(QPaintEvent* event)
{
QPainter painter(this);
QPoint pos[4] = { { 10, 10 }, { 20, 20 }, { 300, 10 }, { 20, 400 } };
painter.drawLines(pos, 4);
}
绘制各种图形
QPoint pos[4] = { { 10, 10 }, { 20, 20 }, { 300, 10 }, { 20, 400 } };
painter.drawLines(pos, 2); // 点的数量最少是线条数量的2倍,要不然会越界,画出来不是想要的线
// 画圆弧
painter.drawArc(50, 10, 20, 20, 10 * 16, 20 * 16); // 后面2位是起始角度和终止角度,要度数乘以16
// 绘制点
painter.drawPoint(100, 100);
// 绘制弦
painter.drawChord(QRect(200, 200, 400, 400), 0 * 16, 180 * 16);
// 绘制多边形
painter.drawPolygon(pos, 4);
painter.drawConvexPolygon(pos, 4); // 同上
// 画折线
QPoint pos2[4] = { { 100, 123 }, { 200, 321 }, { 360, 123 }, { 50, 230 } };
painter.drawPolyline(pos2, 4);
// 画椭圆
painter.drawEllipse(300, 50, 80, 30);
// 画矩形
painter.drawRect(10, 10, 300, 300);
// 画填充矩形
painter.fillRect(30, 30, 60, 60, QGradient::BlackSea);
// 画扇形
painter.drawPie(100, 1, 400, 30, 30 * 16, 200 * 16);
使用画笔QPen
// 设置画笔
painter.setPen(Qt::green);
painter.setPen(Qt::DashDotDotLine); // 设置2次只能生效后面那个,前面那个绿色就不生效
painter.drawRoundedRect(2, 100, 400, 400, 1.1, 2.2);
// 也可以直接定义QPen
QPen pen;
pen.setColor(Qt::red);
pen.setStyle(Qt::DashDotDotLine);
painter.setPen(pen);
QPainterPath path;
for (int i = 0; i <= 100; i++) {
float r = 200 * (1 - sin(i));
int x = 400 - r * cos(i);
int y = 200 - r * sin(i);
if (i == 0)
path.moveTo(x, y);
else
path.lineTo(x, y);
}
painter.drawPath(path);
使用画刷QBrush
QBrush类提供了画刷来对图形进行填充
样式,颜色,纹理填充
系统风格有如下:
QPainter painter(this);
QBrush brush;
brush.setColor(Qt::blue); // 设置画刷颜色
painter.setRenderHint(QPainter::Antialiasing); // 抗锯齿
// 写一个3行5列的不同风格画刷
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
brush.setStyle(Qt::BrushStyle(i * 5 + j));
painter.setBrush(brush);
painter.drawRect(j * 50, i * 50, 50, 50);
}
}
QPixmap pix("C:\\Users\\PVer\\Pictures\\Resource\\派蒙.jpeg");
brush.setTexture(pix); // 纹理填充
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
painter.setBrush(brush);
painter.drawRect(j * 200, i * 100 + 200, 200, 100);
}
} // 如果当前格子放不下原来的图片,剩下的部分填充到相邻的格子里,而不是进行缩放
效果图
渐变填充
#inclue<QLinearGradient> Linear
#include<QRadial[Gradient> Radial
#include <QConicalGradient> Conical
只写一个线性渐变的例子
QLinearGradient lgt(0, 0, 40, 40); // 从点0,0到40,40渐变
lgt.setColorAt(0, Qt::red); // 在0的位置设置红色,位置只能从0到1
lgt.setColorAt(0.6, Qt::blue);
lgt.setColorAt(1, Qt::yellow);
painter.setBrush(lgt);
painter.drawEllipse(0, 0, 200, 200);
// 线性渐变样式设置
lgt.setSpread(QGradient::RepeatSpread);
lgt.setCoordinateMode(QGradient::StretchToDeviceMode); // 绘图设备边缘开始渐变
painter.setBrush(lgt);
painter.drawEllipse(0, 200, 200, 200);
painter.drawEllipse(200, 200, 200, 200);
painter.drawEllipse(400, 200, 200, 200);
坐标变换
- Qpainter自带的变换
QPainter painter(this);
QPixmap pix("C:\\Users\\PVer\\Pictures\\Resource\\派蒙.jpeg");
painter.setBrush(QBrush(pix));
painter.translate(200, 30); // 坐标系平移,原点变成200,30这个点
painter.scale(0.8, 1.2); // 进行缩放,X轴压缩成0.8倍,y拉伸成1.2倍
painter.rotate(90); // 坐标系顺时针旋转90度
painter.drawRect(0, 0, 501, 501);
- 通过QTransform
QPainter painter(this);
QPixmap pix("C:\\Users\\PVer\\Pictures\\Resource\\派蒙.jpeg");
QTransform tsform;
// tsform.rotate(30); // 顺时针旋转30度,默认是Z轴,垂直于X,Y平面的轴
// tsform.rotate(30, Qt::YAxis); // 以Y轴为轴心,顺时针旋转30度
// tsform.translate(10, 10); // 坐标系平移
tsform.shear(0.5, 0.5); // 错切 x旋转0.5Y旋转0.5
painter.setTransform(tsform);
painter.drawPixmap(100, 100, pix);
绘图函数
QImage是为I/O和直接像素访问和操作而设计优化的
QPixmap是为在屏幕上显示图像而设计优化的
QBitmap只是一个继承了QPixmap的方便类,确保深度为1
QPicture类是一个记录和回放QPainter命令的绘图设备
QPixmap pix;
QImage img;
QBitmap bit;
QPicture pic;
QPainter painter(&pix);
pix = QPixmap("C:\\Users\\PVer\\Pictures\\Resource\\派蒙.jpeg");
painter.drawPixmap(0, 0, pix);
pix.save("./pix.png");
img = QImage(size(), QImage::Format_ARGB32);
painter.begin(&img);
painter.drawPixmap(0, 0, pix);
painter.end();
img.save("./img.png");
bit = QBitmap(size());
painter.begin(&bit);
painter.drawPixmap(0, 0, pix);
painter.end();
bit.save("./bit.png");
painter.begin(&pic);
painter.drawPixmap(0, 0, pix);
painter.end();
pic.save("./pic.pic");
// pic图片可以通QPainter重演
painter.begin(this);
pic.load("./pic.pic");
pic.play(&painter);
painter.end();