C++ Qt开发:Charts绘图组件概述
Qt 是一個跨平臺C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺窗體應(yīng)用程序,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現(xiàn)圖形化開發(fā)極大的方便了開發(fā)效率,本章將重點介紹QCharts二維繪圖組件的常用方法及靈活運用。
Qt Charts 提供了一個強大且易于使用的工具集,用于在 Qt 應(yīng)用程序中創(chuàng)建各種類型的圖表和圖形可視化,該模塊提供了多種類型的圖表,包括折線圖、散點圖、條形圖、餅圖等。這使得開發(fā)人員能夠輕松地將數(shù)據(jù)以直觀的方式呈現(xiàn)給用戶,增強應(yīng)用程序的可視化效果。
Qt Charts 組件基于GraphicsView架構(gòu),核心由QChartView和QChart兩個組件構(gòu)成。其中,QChartView的父類是QGraphicsView,它負(fù)責(zé)管理數(shù)據(jù)集的顯示。而QChart則是圖表的主要類,用于定義圖表的結(jié)構(gòu)和樣式。整體來說,QChartView通過顯示QChart來呈現(xiàn)圖表視圖。其中QChart的繼承關(guān)系如下圖所示;
如果要在項目中使用繪圖模塊,則必須在項目的*.pro文件中引用Qt+=charts并在主函數(shù)中包含繪圖頭文件,如下所示;
#include <QtCharts>
using namespace QtCharts;
或者直接使用宏定義的方式;
#include <QtCharts>
Qt_CHARTS_USE_NAMESPACE
此外,為了能夠讓界面支持中文漢字,我們通常會直接引入如下代碼至mainwindow.h頭文件中;
#include <QMainWindow>
#include <QtCharts>
QT_CHARTS_USE_NAMESPACE
// 解決MSVC編譯時,界面漢字亂碼的問題
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
以下是 QChart 類的一些常用方法的概述,說明和表格:
| 方法 | 描述 |
|---|---|
setTitle(const QString &title) |
設(shè)置圖表的標(biāo)題 |
setTitleFont(const QFont &font) |
設(shè)置圖表標(biāo)題的字體 |
setTitleBrush(const QBrush &brush) |
設(shè)置圖表標(biāo)題的畫刷(顏色和填充) |
setTheme(QChart::ChartTheme theme) |
設(shè)置圖表的主題,包括顏色和樣式 |
addSeries(QAbstractSeries *series) |
向圖表中添加數(shù)據(jù)系列 |
removeSeries(QAbstractSeries *series) |
從圖表中移除指定的數(shù)據(jù)系列 |
createDefaultAxes() |
創(chuàng)建默認(rèn)的坐標(biāo)軸 |
setAxisX(QAbstractAxis *axis, QAbstractSeries *series = nullptr) |
設(shè)置圖表的 X 軸。如果未指定系列,則應(yīng)用于所有系列 |
setAxisY(QAbstractAxis *axis, QAbstractSeries *series = nullptr) |
設(shè)置圖表的 Y 軸。如果未指定系列,則應(yīng)用于所有系列 |
legend() |
返回圖表的圖例對象 |
setAnimationOptions(QChart::AnimationOptions options) |
設(shè)置圖表的動畫選項 |
createDefaultGraphicsView() |
創(chuàng)建默認(rèn)的圖形視圖(QGraphicsView),用于顯示圖表 |
addAxis(QAbstractAxis *axis, Qt::Alignment alignment) |
將指定的坐標(biāo)軸添加到圖表中,并指定對齊方式 |
removeAxis(QAbstractAxis *axis) |
從圖表中移除指定的坐標(biāo)軸 |
axisX(QAbstractSeries *series = nullptr) |
返回圖表的 X 軸。如果未指定系列,則返回第一個 X 軸 |
axisY(QAbstractSeries *series = nullptr) |
返回圖表的 Y 軸。如果未指定系列,則返回第一個 Y 軸 |
setPlotAreaBackgroundBrush(const QBrush &brush) |
設(shè)置圖表繪圖區(qū)域的背景畫刷 |
setPlotAreaBackgroundVisible(bool visible) |
設(shè)置圖表繪圖區(qū)域的背景是否可見 |
setBackgroundBrush(const QBrush &brush) |
設(shè)置整個圖表的背景畫刷 |
setBackgroundRoundness(qreal diameter) |
設(shè)置圖表背景的圓角直徑 |
setMargins(const QMargins &margins) |
設(shè)置圖表的外邊距 |
setTheme(QChart::ChartTheme theme) |
設(shè)置圖表的主題 |
注意,上述表格中的方法并非 exhaustive,只是介紹了一些常見的和常用的方法。在實際使用中,可以根據(jù)需要查閱官方文檔獲取更詳細(xì)的信息。
1.1 繪制折線圖
接著我們來創(chuàng)建一個最基本的折線圖,首先需要使用圖形界面中的Graphics View組件做好UI布局,但由于該組件并不是用于繪制圖形的,所以如果需要繪制圖形則要在組件上右鍵,選中提升為按鈕將其提升為繪圖組件,如下圖;
此時會彈出如下所示的提示框,我們直接輸入QChartView類名稱,并點擊添加按鈕,最后選擇提升按鈕,此時組件將將被支持繪制圖形;
為了能讓后續(xù)的代碼能夠更更容易的被讀著理解,此處還需要為讀者提供一份QGraphicsView組件的常用方法,如下表格是QGraphicsView的一些常用方法的概述:
| 方法 | 描述 |
|---|---|
QGraphicsView(QWidget *parent = nullptr) |
默認(rèn)構(gòu)造函數(shù),創(chuàng)建一個QGraphicsView對象。 |
setScene(QGraphicsScene *scene) |
將指定的QGraphicsScene設(shè)置為視圖的場景。 |
scene() const |
獲取當(dāng)前視圖關(guān)聯(lián)的場景。 |
setRenderHint(QPainter::RenderHint hint, bool on = true) |
設(shè)置渲染提示,例如抗鋸齒等。 |
setRenderHints(QPainter::RenderHints hints) |
設(shè)置多個渲染提示。 |
renderHints() const |
獲取當(dāng)前的渲染提示。 |
setViewportUpdateMode(ViewportUpdateMode mode) |
設(shè)置視口更新模式,決定何時重繪視口。 |
setSceneRect(const QRectF &rect) |
設(shè)置場景矩形,指定在視圖中可見的場景區(qū)域。 |
setSceneRect(qreal x, qreal y, qreal w, qreal h) |
設(shè)置場景矩形,指定在視圖中可見的場景區(qū)域。 |
sceneRect() const |
獲取當(dāng)前場景矩形。 |
setTransform(const QTransform &matrix, bool combine = false) |
設(shè)置視圖的坐標(biāo)變換矩陣。 |
resetTransform() |
重置視圖的坐標(biāo)變換矩陣為單位矩陣。 |
translate(qreal dx, qreal dy) |
將視圖進行平移。 |
rotate(qreal angle) |
將視圖進行旋轉(zhuǎn)。 |
scale(qreal sx, qreal sy) |
將視圖進行縮放。 |
resetMatrix() |
將視圖的坐標(biāo)變換矩陣重置為單位矩陣。 |
setViewportMargins(int left, int top, int right, int bottom) |
設(shè)置視口的邊緣,以保留用于顯示視圖的場景區(qū)域之外的空間。 |
setBackgroundBrush(const QBrush &brush) |
設(shè)置視圖的背景刷。 |
viewport() const |
獲取視口窗口部件,即視圖的直接子部件。 |
setOptimizationFlag(OptimizationFlag flag, bool enabled = true) |
啟用或禁用指定的優(yōu)化標(biāo)志,以提高性能。 |
optimizationFlag(OptimizationFlag flag) const |
獲取指定的優(yōu)化標(biāo)志狀態(tài)。 |
centerOn(const QGraphicsItem *item) |
將視圖中心對準(zhǔn)指定的圖形項。 |
centerOn(const QPointF &pos) |
將視圖中心對準(zhǔn)指定的場景坐標(biāo)。 |
setInteractive(bool allowed) |
啟用或禁用與場景中的項的交互。 |
setDragMode(DragMode mode) |
設(shè)置拖動模式,用于選擇或移動項。 |
setViewportMargins(int left, int top, int right, int bottom) |
設(shè)置視口的邊緣,以保留用于顯示視圖的場景區(qū)域之外的空間。 |
viewport() const |
獲取視口窗口部件,即視圖的直接子部件。 |
這些方法提供了對QGraphicsView的各種設(shè)置和操作,用于管理視圖的外觀和行為。可以根據(jù)實際需要選擇適當(dāng)?shù)姆椒ㄟM行使用。
接著,我們來實現(xiàn)一個簡單的繪圖功能,在MainWindow構(gòu)造函數(shù)中我們首先通過new QChart()創(chuàng)建一個圖表類,接著通過使用ui->graphicsView->setChart方法可以將QChart()類附加到QGraphicsView圖形組件上,當(dāng)有了組件指針以后,就可以動態(tài)的通過折線圖的規(guī)則來創(chuàng)建圖例,當(dāng)有了圖例以后則就可以通過series0->append()方法依次向圖形表格中追加記錄。
以下是對功能的概述:
-
創(chuàng)建圖表和序列:
- 創(chuàng)建一個
QChart對象,并設(shè)置圖表標(biāo)題。 - 將圖表添加到
QChartView中,以便在UI中顯示。 - 創(chuàng)建兩個曲線序列
QLineSeries,分別代表一分鐘和五分鐘的系統(tǒng)負(fù)載。 - 將這兩個序列添加到圖表中。
- 創(chuàng)建一個
-
設(shè)置圖表屬性:
- 設(shè)置圖表的渲染提示,以提高圖表的渲染質(zhì)量。
- 設(shè)置圖表的主題色。
-
創(chuàng)建坐標(biāo)軸:
- 創(chuàng)建 X 軸和 Y 軸對象,并設(shè)置它們的范圍、標(biāo)題、格式和刻度。
- 為每個序列設(shè)置相應(yīng)的坐標(biāo)軸。
-
初始化數(shù)據(jù):
- 使用
QRandomGenerator生成介于0和100之間的隨機整數(shù),模擬系統(tǒng)負(fù)載的變化。 - 將生成的隨機整數(shù)添加到兩個曲線序列中,分別對應(yīng)一分鐘和五分鐘的負(fù)載。
- 在X軸上遞增,以模擬時間的推移。
- 使用
-
清空圖例和賦予數(shù)據(jù):
- 獲取序列的指針。
- 清空曲線序列的數(shù)據(jù),以便重新加載新的數(shù)據(jù)。
- 通過循環(huán)生成的隨機數(shù)填充曲線序列。
總體來說,這段代碼創(chuàng)建了一個簡單的系統(tǒng)性能統(tǒng)計圖,其中包括兩條曲線,每條曲線代表不同時間段的系統(tǒng)負(fù)載。通過使用Qt Charts模塊,可以輕松創(chuàng)建并顯示這樣的圖表。
#include <QRandomGenerator>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ---------------------------------------------------
// 創(chuàng)建圖表的各個部件
// ---------------------------------------------------
QChart *chart = new QChart();
chart->setTitle("系統(tǒng)性能統(tǒng)計圖");
// 將Chart添加到ChartView
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 設(shè)置圖表主題色
ui->graphicsView->chart()->setTheme(QChart::ChartTheme(0));
// 創(chuàng)建曲線序列
QLineSeries *series0 = new QLineSeries();
QLineSeries *series1 = new QLineSeries();
series0->setName("一分鐘負(fù)載");
series1->setName("五分鐘負(fù)載");
// 序列添加到圖表
chart->addSeries(series0);
chart->addSeries(series1);
// 其他附加參數(shù)
series0->setPointsVisible(false); // 設(shè)置數(shù)據(jù)點可見
series1->setPointLabelsVisible(false); // 設(shè)置數(shù)據(jù)點數(shù)值可見
// 創(chuàng)建坐標(biāo)軸
QValueAxis *axisX = new QValueAxis; // X軸
axisX->setRange(1, 100); // 設(shè)置坐標(biāo)軸范圍
axisX->setTitleText("X軸標(biāo)題"); // 標(biāo)題
axisX->setLabelFormat("%d %"); // 設(shè)置x軸格式
axisX->setTickCount(3); // 設(shè)置刻度
axisX->setMinorTickCount(3);
QValueAxis *axisY = new QValueAxis; // Y軸
axisY->setRange(0, 100); // Y軸范圍(-0 - 20)
axisY->setTitleText("Y軸標(biāo)題"); // 標(biāo)題
axisY->setLabelFormat("%d %"); // 設(shè)置y軸格式
axisY->setTickCount(3); // 設(shè)置刻度
axisY->setMinorTickCount(3);
// 設(shè)置X于Y軸數(shù)據(jù)集
chart->setAxisX(axisX, series0); // 為序列設(shè)置坐標(biāo)軸
chart->setAxisY(axisY, series0);
chart->setAxisX(axisX, series1); // 為序列設(shè)置坐標(biāo)軸
chart->setAxisY(axisY, series1);
// ---------------------------------------------------
// 開始初始化數(shù)據(jù)
// ---------------------------------------------------
// 獲取指針
series0=(QLineSeries *)ui->graphicsView->chart()->series().at(0);
series1=(QLineSeries *)ui->graphicsView->chart()->series().at(1);
// 清空圖例
series0->clear();
series1->clear();
// 賦予數(shù)據(jù)
qreal t=0,intv=1;
for(int i=1;i<100;i++)
{
// 生成一個介于0和100之間的隨機整數(shù)
int randomInt = QRandomGenerator::global()->bounded(101);
int randomInt2 = QRandomGenerator::global()->bounded(84);
series0->append(t,randomInt2); // 設(shè)置軸粒度以及數(shù)據(jù)
series1->append(t,randomInt); // 此處用隨機數(shù)替代
t+=intv; // X軸粒度
}
}
當(dāng)程序被編譯運行后,讀著可看到如下圖所示的模擬數(shù)據(jù)輸出;
1.2 繪制餅狀圖
接著來實現(xiàn)餅狀圖的繪制,此處我們增加兩個graphicsView組件來分別繪制兩個不同的餅狀圖,餅狀圖A用于統(tǒng)計CPU利用率,由于只有兩個數(shù)據(jù)集,所以只需要構(gòu)建兩個QPieSlice即可,代碼如下所示;
void MainWindow::printA()
{
// 構(gòu)造數(shù)據(jù) [已用CPU%] [剩余CPU%]
QPieSlice *slice_1 = new QPieSlice(QStringLiteral("已使用"), 0.6, this);
slice_1->setLabelVisible(true);
QPieSlice *slice_2 = new QPieSlice(QStringLiteral("可用"), 0.4, this);
slice_2->setLabelVisible(true);
// 將兩個餅狀分區(qū)加入series
QPieSeries *series = new QPieSeries(this);
series->append(slice_1);
series->append(slice_2);
// 創(chuàng)建Chart畫布
QChart *chart = new QChart();
chart->addSeries(series);
// 設(shè)置顯示時的動畫效果
chart->setAnimationOptions(QChart::AllAnimations);
chart->setTitle("系統(tǒng)CPU利用率");
// 將參數(shù)設(shè)置到畫布
ui->graphicsView_A->setChart(chart);
ui->graphicsView_A->setRenderHint(QPainter::Antialiasing);
ui->graphicsView_A->chart()->setTheme(QChart::ChartTheme(0));
}
餅狀圖B的構(gòu)建與A保持一致,只需要根據(jù)規(guī)則定義對圖表中的元素進行增減即可,但需要注意由于餅狀圖100%是最大值,所以再分配時需要考慮到配額的合理性。
void MainWindow::printB()
{
// 構(gòu)造數(shù)據(jù) [C盤%] [D盤%] [E盤%]
QPieSlice *slice_c = new QPieSlice(QStringLiteral("C盤"), 0.2, this);
slice_c->setLabelVisible(true);
QPieSlice *slice_d = new QPieSlice(QStringLiteral("D盤"), 0.3, this);
slice_d->setLabelVisible(true);
QPieSlice *slice_e = new QPieSlice(QStringLiteral("E盤"),0.5,this);
slice_e->setLabelVisible(true);
// 將兩個餅狀分區(qū)加入series
QPieSeries *series = new QPieSeries(this);
series->append(slice_c);
series->append(slice_d);
series->append(slice_e);
// 創(chuàng)建Chart畫布
QChart *chart = new QChart();
chart->addSeries(series);
// 設(shè)置顯示時的動畫效果
chart->setAnimationOptions(QChart::AllAnimations);
chart->setTitle("系統(tǒng)磁盤信息");
// 將參數(shù)設(shè)置到畫布
ui->graphicsView_B->setChart(chart);
ui->graphicsView_B->setRenderHint(QPainter::Antialiasing);
// 設(shè)置不同的主題
ui->graphicsView_B->chart()->setTheme(QChart::ChartTheme(3));
}
運行上述程序,則可以輸出兩個不同的餅狀圖,如下圖所示;
1.3 繪制柱狀圖
與餅狀圖的繪制方法一致,在繪制柱狀圖時只需要根據(jù)QBarSeries類的定義對特有元素進行填充即可,當(dāng)數(shù)據(jù)集被填充后既可以直接調(diào)用繪圖方法將數(shù)據(jù)刷新到組件上。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 創(chuàng)建人名
QBarSet *set0 = new QBarSet("張三");
QBarSet *set1 = new QBarSet("李四");
QBarSet *set2 = new QBarSet("王五");
// 分別為不同人添加bu不同數(shù)據(jù)集
*set0 << 1 << 2 << 8 << 4 << 6 << 6;
*set1 << 5 << 2 << 5 << 4 << 5 << 3;
*set2 << 5 << 5 << 8 << 15 << 9 << 5;
// 將數(shù)據(jù)集關(guān)聯(lián)到series中
QBarSeries *series = new QBarSeries();
series->append(set0);
series->append(set1);
series->append(set2);
// 增加頂部提示
QChart *chart = new QChart();
chart->addSeries(series);
chart->setTitle("當(dāng)前人數(shù)統(tǒng)計柱狀圖");
chart->setAnimationOptions(QChart::SeriesAnimations);
// 創(chuàng)建X軸底部提示
QStringList categories;
categories << "周一" << "周二" << "周三" << "周四" << "周五" << "周六";
QBarCategoryAxis *axis = new QBarCategoryAxis();
axis->append(categories);
chart->createDefaultAxes();
chart->setAxisX(axis, series);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
// 將參數(shù)設(shè)置到畫布
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 設(shè)置主題
ui->graphicsView->chart()->setTheme(QChart::ChartTheme(0));
}
運行代碼后則可以輸出如下圖所示的三個人的柱狀統(tǒng)計圖;
至此本章內(nèi)容就結(jié)束了,通過本章內(nèi)容讀著應(yīng)該能掌握GraphicsView繪圖組件是如何提升的,并如何利用該組件實現(xiàn)簡單的繪制工作,從下一章開始我們將依次深入分析常用的圖形類,并實現(xiàn)一個更加實用的小功能,能夠讓讀者學(xué)以致用充分發(fā)揮Qt圖形組件的強大功能。
總結(jié)
以上是生活随笔為你收集整理的C++ Qt开发:Charts绘图组件概述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拼多多百亿补贴是正品吗 拼多多百亿补贴是
- 下一篇: “做开源犹如养护花朵,花开需要时间”|2