QT—绘制其他问题

x33g5p2x  于2022-07-04 转载在 其他  
字(2.4k)|赞(0)|评价(0)|浏览(422)

1. 重绘事件

前面讲到的所有绘制操作都是在重绘事件处理函数 paintEvent()中完成的,它是QWidget类中定义的函数。
一个重绘事件用来重绘一个部件的全部或者部分区域

下面几个原因中的任意一个都会发生重绘事件:

  • repaint()函数或者update()函数被调用;
  • 被隐藏的部件现在被重新显示;
  • 其他一些原因;

大部分部件可以简单地重绘它们的全部界面,但是一些绘制比较慢的部件需要进行优化而只绘制需要的区域(可以使用QPaintEvent::region()来获取该区域),这种速度上的优化不会影响结果。

Qt也会通过合并多个重绘事件为一个事件来加快绘制,当update()函数被调用多次,或者窗口系统发送了多个重绘事件时,那么Qt就会合并这些事件成为一个事件,而这个事件拥有最大的需要重绘的区域。update()函数不会立即进行重绘,要等到Qt返回主事件循环后才会进行,所以多次调用update()函数一般只会引起一次paintEvent()函数调用。
而调用repaint()函数会立即调用paintEvent()函数来重绘部件,只有在必须立即进行重绘操作的情况下(比如在动画中) ,才使用repaint()函数

update()允许Qt优化速度和减少闪烁,但是repaint()函数不支持这样的优化,所以建议―般情况下尽可能使用update()函数

还要说明一下,在程序开始运行时就会自动发送重绘事件而调用 paintEvent()函数。另外,不要在paintEvent()函数中调用update()或者repaint()函数

重绘事件发生时,要更新的区域一般会被擦除,然后在部件的背景上进行绘制
部件的背景一般可以使用setBackgroundRole()来指定
然后使用setAutoFillBackground( true)来启用指定的颜色。

例如,使界面显示比较深的颜色,则可以在部件的构造函数中添加如下代码:

setBackgroundRole(QPalette::Dark); //背景黑色
setAutoFillBackground(true); //启用设置的背景色

2. 剪切

QPainter可以剪切任何的绘制操作,它可以剪切一个矩形、一个区域或者一个路径中的内容,这分别可以使用setClipRect( ) , setClipRegion()和 setClipPath()函数来实现。

剪切会在QPainter的逻辑坐标系统中进行。
下面的代码实现了剪切一个矩形中的文字:

QPainter painter(this);
 painter.setClipRect(10,0,20,10); //剪贴
 painter.drawText(10,10,tr("img")); //绘字,img

3. 读取和写入图像

要读取图像,最普通的方法是1. 使用QImage或者QPixmap的构造函数,或者调用2. QImage::load()和QPixmap::load()函数。
Qt中还有一个QImageReader类,该类提供了一个格式无关的接口,可以从文件或者其他设备中读取图像QImageReader类可以在读取图像时提供更多的控制,例如,可以使用setScaledSize()函数将图像以指定的大小进行读取,还可以使用setClipRect()读取图像的一个区域。
由于依赖于图像格式底层的支持,QImageReader的这些操作可以节省内存和加快图像的读取。

另外,Qt还提供了QImageWriter类存储图像,它支持设置图像格式的特定选项,比如伽玛等级、压缩等级和品质等。当然,如果不需要设置这些选项,那么可以直接使用QImage::save()和 QPixmap::save()函数

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;
    // 加载一张图片
    image.load("../mydrawing3/image.png");
    // 输出图片的一些信息
    qDebug() << image.size() << image.format() << image.depth();
    // 在界面上绘制图片
    painter.drawImage(QPoint(10, 10), image);
    // 获取镜像图片
    QImage mirror = image.mirrored();
    // 将图片进行扭曲
    QTransform transform;
    transform.shear(0.2, 0);
    QImage image2 = mirror.transformed(transform);
    painter.drawImage(QPoint(10, 160), image2);
    // 将镜像图片保存到文件
    image2.save("../mydrawing3/mirror.png");
}

保存

验证

4. 播放gif动画

QMovie类是使用QImageReader来播放动画的便捷类,使用它可以播放不带声音的简单的动画,比如gif文件格式。这个类提供了很方便的函数来进行动画的开始、暂停和停止等操作。

后面会讲

5. 渲染SVG文件

可缩放矢量图形(Scalable Vector Graphics,SVG)是一个使用XML来描述二维图形和图形应用程序的语言

在Qt中可以使用QSvgWidget类加载一个SVG文件,而使用QSvgRenderer类QSvgWidget中进行SVG文件的渲染

这两个类的使用很简单,这里就不再讲述,可以参考SVG Generator Example和SVG Viewer Example示例程序。

/
/
/
/

/
/
/

/如果还有其余再补充。

相关文章