绘图事件
绘图事件重写的情景
- 当你需要创建一个自定义控件,并且这个控件需要显示特殊的图形、颜色或形状时,重写
paintEvent
是必要的。例如,如果你需要绘制一个自定义的进度条、按钮、图表等 - 当你需要在窗口中绘制复杂的图形,或者在应用程序中实现动画时,
paintEvent
可以用来每次刷新窗口内容
示例
- 首先需要在窗口的头文件声明这方法,表示要重写
- 然后书写具体规则
void MainWindow::paintEvent(QPaintEvent *) {
// 实例化画家对象 this 指定的是绘图设备
QPainter painter(this);
// 设置画笔
QPen pen(QColor(255,0,0));
// 设置画笔宽度
pen.setWidth(3);
// 设置画笔风格
pen.setStyle(Qt::DotLine);
// 让画家 使用这个笔
painter.setPen(pen);
// 设置画刷,寄填充颜色
QBrush brush(Qt::cyan);
// 设置画刷风格
brush.setStyle(Qt::Dense7Pattern);
// 让画家使用画刷
painter.setBrush(brush);
// 画线
painter.drawLine(QPoint(0,0), QPoint(100,100));
// 画圆 椭圆
painter.drawEllipse( QPoint(100,100), 50,50);
// 画矩形
painter.drawRect(QRect(20,20,50,50));
// 画文字,这个使用画刷不会填充,且这个矩形没有线框,默认
painter.drawText(QRect(10,200,150,50), "好好学习,天天向上");
}
高级设置
void MainWindow::paintEvent(QPaintEvent *) {
QPainter painter(this);
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));
// 让画家移动到 (100, 0) 位置再画,此时以画家为基准,在 (20, 20) 位置画
painter.translate(100,0);
// 保存画家状态
painter.save();
painter.drawRect(QRect(20,20,50,50));
translate(150, 0);
// 恢复画家之前保存的状态
painter.restore();
}
利用画家画资源图片,并且实现点击按钮就移动图片
// 首先在 mainwindow 头文件定义一个变量 posX,作为移动的指标
// 然后在 mainwindow.ui 中放一个按钮,取名为 btn
void MainWindow::paintEvent(QPaintEvent *) {
QPainter painter(this);
// 超出屏幕范围,就从 0 开始
if(posX > this->width()) {
posX = 0;
}
painter.drawPixmap(posX, 0, QPixmap(":/111.png"));
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
connect(ui->btn, &QPushButton::clicked, this, [=]() {
posX += 20;
// 如果要手动调用绘图事件 用 update 更新
update();
});
}
绘图设备
绘图设备简单来说就是绘图所在地,也就是画的东西画在上面
QPixmap
专门为图像在屏幕上的显示做了优化QBitmap
是QPixmap
的一个子类,只有黑白两种颜色QImage
专门为图像的像素级访问做了优化,也就是可以修改图片中的像素QPicture
是用来记录和重现QPainter
的各条命令- 上面的案例中在窗口画画,是因为串口是绘图设备,
MainWindow
继承QWidget
,QWidget
继承QObject
和QPaintDevice
,能够在窗口上画画
QPixmap
// QPixmap
// 定义绘图设备的大小
QPixmap pix(300,300);
// 填充颜色(默认为黑色)
pix.fill(Qt::white);
// 声明画家
QPainter painter(&pix);
painter.setPen(QPen(Qt::green)); // QPen 是画笔
// 画椭圆(圆)
painter.drawEllipse(QPoint(150,150), 100,100); // 圆心,两个半径,一样就是圆
// 保存,保存在 E 盘,名字叫 pix.png
// 程序运行后,在 E 盘就能看到这个图片
pix.save("E:\\pix.png");
QImage
// QImage 绘图设备,后面参数是格式,查阅文档填写
QImage img(300,300, QImage::Format_RGB32);
img.fill(Qt::white);
QPainter painter(&img);
painter.setPen(QPen(Qt::blue));
painter.drawEllipse(QPoint(150,150),100,100);
//保存
img.save("E:\\img.png");
对像素修改例子
// 重写 painEvent 事件,需要现在 mainwindow 头文件定义
void MainWindow::paintEvent(QPaintEvent *) {
QPainter painter(this); // 这里 this 是指在这个窗口绘图、
// 利用&Image对像素进行修改
QImage img;
img.load(":/111.png");
// 修改像素点,会看到左上角部分有红色的矩形,这就是修改的
for(int i = 50; i < 100; i++) {
for(int j = 50; j < 100; j++) {
QRgb value = qRgb(255,0,0);
img.setPixel(i, j, value);
}
}
// 在 (0, 0) 处绘图
painter.drawImage(0, 0, img);
}
QPicture
QPicture pic;
QPainter painter;
// 开始往 pic 上画
painter.begin(&pic);
painter.setPen(QPen(Qt::cyan));
painter.drawEllipse(QPoint(150,150),100,100);
// 结束画画
painter.end();
//保存到磁盘
pic.save("E:\\pic.txt");
// 重现
QPainter painter1(this);
// 重现 QPicture 的绘图指令
QPicture pic1;
pic1.load("E:\\pic.txt");
painter.drawPicture(0, 0, pic);