目录
基础效果图
前言
使用Qt自定义折线图,可以自己控制折线图的重绘规则,究竟是每添加一个数据就刷新整个折线图,还是只刷新部分折线图。
我把折线图分为以下两类:
- 坐标系是静态的,折线图更新快。
- 坐标系是动态的,数据的变化更为明显。
设计要点
界面
1.线型的美化
2.给每个数据点设置一个圆点,突出一下
功能
1.坐标轴的绘制
2. 缩放
3. 拖拽
4.数据点的查询
理论学习
这里只总结这一次代码需要知道的理论知识,带着问题去学习。
问题1:QT窗口的刷新机制,何时会进入paintEvent?
void QWidget:paintEvent(QPaintEvent *event) [virtual protected]
这个event函数可以被它的子类重构,以接收处理重绘事件。
这个函数被调用的场景包括以下几种:
repaint()或者update()被调用时
这个控件出现且没有被其他窗口挡住。
其他原因比如界面的缩放、移动等
许多控件被要求重绘时,都会重绘整个界面,但是有些控件可能需要优化重绘,于是,我们可以通过设置QPaintEvent::region(),这样就可以只更新指定的区域。
Qt也支持将多个区域的重绘合并为一个区域的重绘,当update()函数被调用多次或者窗口系统发送了多次paint事件,Qt会将涉及到的区域合并为一个更大的区域。但是repaint()函数不会有以上的优化,每次它被调用就会立刻以最快速度重绘需要重绘的区域,所以Qt建议不管什么情况下,都尽量使用update()函数。
当重绘事件发生时,被更新的区域首先会被擦除,但你可以自定义控件的背景。
注意:自Qt 4.0 版本开始,QWidget就已经自动实现了双缓存,所以编程人员不需要为了避免界面闪烁,而在paintEvent()函数中编写有关双缓存的代码。
问题2:QPainter的使用
绘制折线图,主要用到QPainter的四个函数,分别起:构造、绘制直线、绘制字符串的作用、绘制圆。
问题3:怎么做到“部分刷新”以节约时间。
setAttribute(Qt::WA_OpaquePaintEvent); //实现部分重绘
代码实战
界面的美化
这里只提一个,就是线型的美化,用QPainter去绘制直线时,如果直接使用,绘制的线性会受画线的规则影响,加一个设置之后,可以美化直线,当然,缺点就是:多了运算量,目的是通过消除锯齿现象来美化直线。
美化时需要对QPainter进行设置:
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true); //添加反走样可以使线型更加好看
美化前后对比图:


图中,因为数据源是随机产生的,所以前后数据不一致,但是光是从这两张图里,我们也可以可以看出第一张图里边,锯齿现象非常明显,而图二通过颜色的重新计算,用明亮度消除了锯齿带来的不良影响。
可能有人会想问,为什么不默认打开反走样呢?
这是因为,反走样是一种比较复杂的算法,在一些对图像质量要求不高的应用中,是不需要进行反走样的。
为了提高效率,一般的图形绘制系统,如Java2D、OpenGL之类都是默认不进行反走样的。
还有一个疑问,既然反走样比不反走样的图像质量高很多,不进行反走样的绘制还有什么作用呢?
前面说的是一个方面,也就是,在一些对图像质量要求不高的环境下,或者说性能受限的环境下,
比如嵌入式和手机环境,是