当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!

版权声明:本文原创于yafeilinux的CSDN博客,转载请注明出处:https://blog.csdn.net/yafeilinux/article/details/86029474


当使用图表时我们大多关心数据本身,而对于实现形式,一般会使用标准的样式。但是在一些场合,我们更关心数据的展示效果而不是数字本身。对于下面两张图片效果,你更喜欢哪一个?

是标准化的坐标网格:

当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!_第1张图片

还是梦幻的科技元素:

 

当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!_第2张图片

 

如果只看静态图片还是没有感觉,那就看下动态效果吧!

 

 

很炫酷,不是吗?下面就跟随我来实现科幻的数据曲线吧!

 

 

 

环境:Windows 7 + Qt 5.12.0

 

第一步 创建一个曲线图表


 

注意:在安装Qt时请务必选择Qt Charts模块,不然该模块将无法使用。

 

首先创建一个Qt Quick Application - Empty应用,完成后修改main.qml文件如下:

 

import QtQuick 2.9
import QtQuick.Window 2.2
import QtCharts 2.3

Window {
    visible: true
    width: 800
    height: 480

    ChartView {
        id: chartView
        anchors.fill: parent
        antialiasing: true

        SplineSeries {
            name: "SplineSeries"
            XYPoint { x: 0; y: 0.0 }
            XYPoint { x: 1.1; y: 3.2 }
            XYPoint { x: 1.9; y: 2.4 }
            XYPoint { x: 2.1; y: 2.1 }
            XYPoint { x: 2.9; y: 2.6 }
            XYPoint { x: 3.4; y: 2.3 }
            XYPoint { x: 4.1; y: 3.1 }
        }
    }
}

 

但现在程序还无法运行,因为Qt Charts模块是基于Qt图形视图框架的,为了使用Qt Charts模块,还需要在main.cpp文件中将:

#include 

 

修改为:

#include 

 

然后将:

QGuiApplication app(argc, argv);

 

修改为:

QApplication app(argc, argv);

 

接下来到.pro文件中添加widgets模块调用,即:

QT += quick widgets

 

这样就可以编译运行程序了,效果如下图所示。

 

当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!_第3张图片

 

第二步 动态添加数据


 

首先我们需要提供要显示的数据,这里使用外部的XML文件来提供数据,为了简便,直接使用了Qt示例程序中的数据来进行演示,文件名称为speed.xml,我们将该文件添加到资源文件中。数据内容格式如下:

 



    
        0
        Fittipaldi
        104.12
     
... ...

 

然后使用XmlListModel来解析数据,需要先添加导入语句:

import QtQuick.XmlListModel 2.0

 

然后添加如下代码:

 

XmlListModel {
    id: speedsXml
    source: "speed.xml"
    query: "/results/row"

    XmlRole { name: "speedTrap"; query: "speedTrap/string()" }
    XmlRole { name: "driver"; query: "driver/string()" }
    XmlRole { name: "speed"; query: "speed/string()" }

    onStatusChanged: {
        if (status == XmlListModel.Ready) {
            timer.start();
        }
    }
}

 

解析完数据后我们通过定时器来动态加载数据,先在根对象中新建一个属性,用于计数:

property int currentIndex: -1

 

然后添加定时器的定义:

 

Timer {
    id: timer
    interval: 800
    repeat: true
    triggeredOnStart: true
    running: false
    onTriggered: {
        currentIndex++;

        if (currentIndex < speedsXml.count) {
            var lineSeries = chartView.series(speedsXml.get(0).driver);
            if (!lineSeries) {
                lineSeries = chartView.createSeries(ChartView.SeriesTypeSpline,
                                                    speedsXml.get(0).driver);
                chartView.axisY().min = 0;
                chartView.axisY().max = 250;
                chartView.axisY().tickCount = 6;
                chartView.axisY().titleText = "speed (kph)";
                chartView.axisX().titleText = "speed trap";
                chartView.axisX().labelFormat = "%.0f";
                lineSeries.color = "#87CEFA"
                chartView.animationOptions = ChartView.SeriesAnimations
            }

            lineSeries.append(speedsXml.get(currentIndex).speedTrap,
                              speedsXml.get(currentIndex).speed);

            if (speedsXml.get(currentIndex).speedTrap > 3) {
                chartView.axisX().max = 
                        Number(speedsXml.get(currentIndex).speedTrap)+1;
            } else {
                chartView.axisX().max = 5;
                chartView.axisX().min = 0;
            }
            chartView.axisX().tickCount = chartView.axisX().max 
                                          - chartView.axisX().min + 1;
        } else {
            timer.stop();
            chartView.animationOptions = ChartView.AllAnimations;
            chartView.axisX().min = 0;
            chartView.axisX().max = speedsXml.get(currentIndex - 1).speedTrap;
        }
    }
}

 

这里在定时器中,每隔0.8秒就添加一组数据,在第一次运行时还创建了SplineSeries曲线图,因为这次我们重点不是讲解图表的基础知识,所以就不再对代码进行过多讲解。

 

最后,我们需要将前面在ChartView对象中定义的SplineSeries代码删除或注释掉,下面可以运行程序,看下效果了。

 

当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!_第4张图片

 

第三步 使用图形特效


 

接下来我们使用Qt Graphicl Effects为图表添加图形效果,在这之前,需要先对图表进行一些必要的处理。

 

首先在ChartView对象中添加代码,将图表背景设置为透明,并让图例隐藏:

 

backgroundColor: "transparent"
legend.visible: false

 

然后到Timer对象中,在:if (!lineSeries) {}最后添加如下代码来隐藏XY轴:

 

chartView.axisX().visible = false
chartView.axisY().visible = false

 

现在运行程序,效果是这样的:

 

当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!_第5张图片

 

接下来先添加导入语句:

import QtGraphicalEffects 1.12

 

然后在根对象中添加如下代码:

 

Glow {
    id:glow
    anchors.fill: chartView
    radius: 18
    samples: 37
    color: "#87CEFA"
    source: chartView
}

RadialBlur {
    anchors.fill: chartView
    source: chartView
    angle: 360
    samples: 20
}

ZoomBlur {
    anchors.fill: chartView
    source: chartView
    length: 24
    samples: 20
}

 

这里对图表分别使用了发光、镜像模糊和缩放模糊三种特效,更改不同的参数,特效会有所不同,大家可以多尝试下。下面来看下运行效果,现在已经出现梦幻曲线了,其实白色背景也蛮漂亮的(由于截图被压缩,背景效果显示不是很明显)。

 

当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!_第6张图片

 

为了更加突出发光效果,我们将背景设置为黑色,在Window根对象的开始添加一行代码:

color: "black"

 

现在运行程序,效果好像更加明显了。

 

当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!_第7张图片

 

第四步 化腐朽为神奇


 

其实现在特效曲线已经实现了,但看上去有点单薄,为了进一步突出科技效果,我们为其添加一些装饰。

我们在ChartView对象中添加子对象:

 

Image {
    id: img
    source: "circle.png"
    width: 100; height: 100
    x: -10; y: 230
    visible: true
    Behavior on rotation {
        NumberAnimation {
            duration: 800
            easing.type: Easing.InOutElastic;
            easing.amplitude: 2.0;
            easing.period: 1.5
        }
    }
}

Text {
    id:txt
    width: 200; height: 20
    x: 350; y: 55
    font.pointSize: 20
    font.family: "Cambria"
    color: "#F8F8FF"
}

 

这里添加了一个图片和一个文本,图片作为曲线发射器,文本用来显示曲线数据,为了让二者可以共享图表的图形效果,这里将他们作为图表的子对象。

 

下面添加代码来为文本提供数据,并且让图片旋转起来。在Timer对象的

 

lineSeries.append(speedsXml.get(currentIndex).speedTrap,
                          speedsXml.get(currentIndex).speed);

 

语句下面添加如下代码:

 

txt.text = speedsXml.get(currentIndex).speed;

img.rotation += 360

 

运行程序,效果是这样的。

 

当Qt Charts遇上Qt Graphical Effects,梦幻科技曲线!_第8张图片

 

最后我们再添加代码,来为图表添加一个边框,在根对象最后添加如下代码:

 

Image {
    id: border
    source: "border.png"
    anchors.fill: parent
}

Glow {
    anchors.fill: border
    radius: 18
    samples: 37
    color: "#87CEFA"
    source: border
}

 

这里为边框也使用了发光特效,进一步突出科技感。现在,整个图表美化的过程就完成了,大家可以尝试进行修改,做出其他炫酷效果。

 

结语


 

要做出一些特殊效果,其实关键在于两点,一是知识面,二是套路。没有知识面,啥都不知道,那就什么也别说了。当有了知识面之后,知道什么模块能起到什么作用,下面就是学习一些套路,这里所说的套路既是经验也是规律,比如,你知道PS出来的图片为什么好看吗?你知道饭店炒的菜为什么比家里味道浓吗?编程的道理是相通的。

 

源码下载:https://github.com/yafeilinux/effctchart

 

你可能感兴趣的:(Qt相关)