Qt学习之路(24):QPainter

多些大家对我的支持啊!有朋友也提出,前面的几节有关event的教程缺少例子。因为event比较难做例子,也就没有去写,只是把大概写了一下。今天带来的是新的部分,有关Qt的2D绘图。这部分不像前面的内容,还是比较好理解的啦!所以,例子也会增加出来。

有人问豆子拿Qt做什么,其实,豆子就是在做一个Qt的画图程序,努力朝着Photoshop和GIMP的方向发展。但这终究要经过很长的时间、很困难的路程的,所以也放在网上开源,有兴趣的朋友可以来试试的呀…

好了,闲话少说,来继续我们的学习吧!

Qt的绘图系统允许使用相同的API在屏幕和打印设备上进行绘制。整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类。

QPainter用来执行绘制的操作;QPaintDevice是一个二维空间的抽象,这个二维空间可以由QPainter在上面进行绘制;QPaintEngine提供了画笔painter在不同的设备上进行绘制的统一的接口。QPaintEngine类用在QPainter和 QPaintDevice之间,并且通常对开发人员是透明的,除非你需要自定义一个设备,这时候你就必须重新定义QPaintEngine了。

下图给出了这三个类之间的层次结构(出自Qt API 文档):


这种实现的主要好处是,所有的绘制都遵循着同一种绘制流程,这样,添加可以很方便的添加新的特性,也可以为不支持的功能添加一个默认的实现方式。另外需要说明一点,Qt提供了一个独立的QtOpenGL模块,可以让你在Qt的应用程序中使用OpenGL功能。该模块提供了一个OpenGL的模块,可以像其他的Qt组件一样的使用。它的不同之处在于,它是使用OpenGL作为显示技术,使用OpenGL函数进行绘制。对于这个组件,我们以后会再介绍。

通过前面的介绍我们知道,Qt的绘图系统实际上是说,使用QPainter在QPainterDevice上面进行绘制,它们之间使用QPaintEngine进行通讯。好了,下面我们来看看怎么使用QPainter。

首先我们定义一个组件,同前面的定义类似:

class PaintedWidget : public QWidget
{
public:
PaintedWidget();
protected:
void paintEvent(QPaintEvent *event);
};

这里我们只定义了一个构造函数,并且重定义paintEvent()函数。从名字就可以看出,这实际上是一个事件的回调函数。请注意,一般而言,Qt的事件函数都是protected的,所以,如果你要重写事件,就需要继承这个类了。至于事件相关的东西,我们在前面的内容已经比较详细的叙述了,这里不再赘述。

构造函数里面主要是一些大小之类的定义,这里不再详细说明:

PaintedWidget::PaintedWidget()
{
resize(800, 600);
setWindowTitle(tr("Paint Demo"));
}

我们关心的是paintEvent()函数的实现:

void PaintedWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawLine(80, 100, 650, 500);
painter.setPen(Qt::red);
painter.drawRect(10, 10, 100, 400);
painter.setPen(QPen(Qt::green, 5));
painter.setBrush(Qt::blue);
painter.drawEllipse(50, 150, 400, 200);
}

时间: 2024-12-02 10:15:10

Qt学习之路(24):QPainter的相关文章

Qt学习之路(25):QPainter(续)

首先还是要先把上次的代码拿上来. void PaintedWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.drawLine(80, 100, 650, 500); painter.setPen(Qt::red); painter.drawRect(10, 10, 100, 400); painter.setPen(QPen(Qt::green, 5)); painter.setBrush(Qt::b

Qt 学习之路 2 --- 读书笔记

一.文章来由 来自豆子老师非常好的一本Qt教程,但是只有网络版,所以用这个做笔记了,不动笔墨不读书嘛~~ 二.读书笔记 1.Qt 学习之路 2(2):Qt 简介 1.1 关于 Qt 的一站式解决 Qt 是一个著名的 C++ 应用程序框架.但并不只是一个 GUI 库,因为 Qt 十分庞大,并不仅仅是 GUI 组件.使用 Qt,在一定程度上你获得的是一个"一站式"的解决方案:不再需要研究 STL,不再需要 C++ 的,不再需要到处去找解析 XML.连接数据库.访问网络的各种第三方库,因为

Qt学习之路(23):自定义事件

Qt允许你创建自己的事件类型,这在多线程的程序中尤其有用,当然,也可以用在单线程的程序中,作为一种对象间通讯的机制.那么,为什么我需要使用事件,而不是使用信号槽呢?主要原因是,事件的分发既可以是同步的,又可以是异步的,而函数的调用或者说是槽的回调总是同步的.事件的另外一个好处是,它可以使用过滤器. Qt中的自定义事件很简单,同其他类似的库的使用很相似,都是要继承一个类进行扩展.在Qt中,你需要继承的类是QEvent.注意,在Qt3中,你需要继承的类是QCustomEvent,不过这个类在Qt4中

Qt学习之路(30):Graphics View Framework

现在基本上也已经到了2D绘图部分的尾声,所谓重头戏都是在最后压轴的,现在我们就要来看看在绘图部分功能最强大的Graphics View.我们经常说KDE桌面,新版本的KDE桌面就是建立在Graphics View的基础之上,可见其强大之处. Qt的白皮书里面这样写道:"Qt Graphics View 提供了用于管理和交互大量定制的 2D 图形对象的平面以及可视化显示对象的视图 widget,并支持缩放和旋转功能.Graphics View 使用 BSP(二进制空间划分)树形可非常快速地找到对象

Qt学习之路(29):绘图设备

绘图设备是指继承QPainterDevice的子类.Qt一共提供了四个这样的类,分别是QPixmap.QBitmap.QImage和 QPicture.其中,QPixmap专门为图像在屏幕上的显示做了优化,而QBitmap是QPixmap的一个子类,它的色深限定为1,你可以使用 QPixmap的isQBitmap()函数来确定这个QPixmap是不是一个QBitmap.QImage专门为图像的像素级访问做了优化. QPicture则可以记录和重现QPainter的各条命令.下面我们将分两部分介绍

Qt学习之路(28):坐标变换

经过前面的章节,我们已经能够画出一些东西来,主要就是使用QPainter的相关函数.今天,我们要看的是QPainter的坐标系统. 同很多坐标系统一样,QPainter的默认坐标的原点(0, 0)位于屏幕的左上角,X轴正方向是水平向右,Y轴正方向是竖直向下.在这个坐标系统中,每个像素占据1 x 1的空间.你可以把它想象成是一张坐标值,其中的每个小格都是1个像素.这么说来,一个像素的中心实际上是一个"半像素坐标系",也就是说,像素(x, y)的中心位置其实是在(x + 0.5, y +

Qt学习之路(27):渐变填充

前面说了有关反走样的相关知识,下面来说一下渐变.渐变是绘图中很常见的一种功能,简单来说就是可以把几种颜色混合在一起,让它们能够自然地过渡,而不是一下子变成另一种颜色.渐变的算法比较复杂,写得不好的话效率会很低,好在很多绘图系统都内置了渐变的功能,Qt也不例外.渐变一般是用在填充里面的,所以,渐变的设置就是在QBrush里面. Qt提供了三种渐变画刷,分别是线性渐变(QLinearGradient).辐射渐变(QRadialGradient).角度渐变(QConicalGradient).如下图所

Qt学习之路(26):反走样

今天继续前面的内容.既然已经进入2D绘图部分,那么就先继续研究一下有关QPainter的东西吧! 反走样是图形学中的重要概念,用以防止"锯齿"现象的出现.很多系统的绘图API里面都会内置了反走样的算法,不过默认一般都是关闭的,Qt也不例外.下面我们来看看代码.这段代码仅仅给出了paintEvent函数,相信你可以很轻松地替换掉前面章节中的相关代码. void PaintedWidget::paintEvent(QPaintEvent *event) { QPainter painter

Qt学习之路(12):菜单和工具条

在前面的QMainWindow的基础之上,我们开始着手建造我们的应用程序.虽然现在已经有一个框架,但是,确切地说我们还一行代码没有写呢!下面的工作就不那么简单了!在这一节里面,我们要为我们的框架添加菜单和工具条. 就像Swing里面的Action一样,Qt里面也有一个类似的类,叫做QAction.顾名思义,QAction类保存有关于这个动作,也就是action的信息,比如它的文本描述.图标.快捷键.回调函数(也就是信号槽),等等.神奇的是,QAction能够根据添加的位置来改变自己的样子 --如