C++ Qt開發:Charts繪圖組件概述

来源:https://www.cnblogs.com/LyShark/archive/2023/12/22/17922299.html
-Advertisement-
Play Games

Qt 是一個跨平臺C++圖形界面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹`QCharts`二維繪圖組件的常用方法及靈活運用。Qt Charts 提供了一個強大且易於使用的工具集,用於在 ... ...


Qt 是一個跨平臺C++圖形界面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹QCharts二維繪圖組件的常用方法及靈活運用。

Qt Charts 提供了一個強大且易於使用的工具集,用於在 Qt 應用程式中創建各種類型的圖表和圖形可視化,該模塊提供了多種類型的圖表,包括折線圖、散點圖、條形圖、餅圖等。這使得開發人員能夠輕鬆地將數據以直觀的方式呈現給用戶,增強應用程式的可視化效果。

Qt Charts 組件基於GraphicsView架構,核心由QChartViewQChart兩個組件構成。其中,QChartView的父類是QGraphicsView,它負責管理數據集的顯示。而QChart則是圖表的主要類,用於定義圖表的結構和樣式。整體來說,QChartView通過顯示QChart來呈現圖表視圖。其中QChart的繼承關係如下圖所示;

如果要在項目中使用繪圖模塊,則必須在項目的*.pro文件中引用Qt+=charts併在主函數中包含繪圖頭文件,如下所示;

#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) 設置圖表的標題
setTitleFont(const QFont &font) 設置圖表標題的字體
setTitleBrush(const QBrush &brush) 設置圖表標題的畫刷(顏色和填充)
setTheme(QChart::ChartTheme theme) 設置圖表的主題,包括顏色和樣式
addSeries(QAbstractSeries *series) 向圖表中添加數據系列
removeSeries(QAbstractSeries *series) 從圖表中移除指定的數據系列
createDefaultAxes() 創建預設的坐標軸
setAxisX(QAbstractAxis *axis, QAbstractSeries *series = nullptr) 設置圖表的 X 軸。如果未指定系列,則應用於所有系列
setAxisY(QAbstractAxis *axis, QAbstractSeries *series = nullptr) 設置圖表的 Y 軸。如果未指定系列,則應用於所有系列
legend() 返回圖表的圖例對象
setAnimationOptions(QChart::AnimationOptions options) 設置圖表的動畫選項
createDefaultGraphicsView() 創建預設的圖形視圖(QGraphicsView),用於顯示圖表
addAxis(QAbstractAxis *axis, Qt::Alignment alignment) 將指定的坐標軸添加到圖表中,並指定對齊方式
removeAxis(QAbstractAxis *axis) 從圖表中移除指定的坐標軸
axisX(QAbstractSeries *series = nullptr) 返回圖表的 X 軸。如果未指定系列,則返回第一個 X 軸
axisY(QAbstractSeries *series = nullptr) 返回圖表的 Y 軸。如果未指定系列,則返回第一個 Y 軸
setPlotAreaBackgroundBrush(const QBrush &brush) 設置圖表繪圖區域的背景畫刷
setPlotAreaBackgroundVisible(bool visible) 設置圖表繪圖區域的背景是否可見
setBackgroundBrush(const QBrush &brush) 設置整個圖表的背景畫刷
setBackgroundRoundness(qreal diameter) 設置圖表背景的圓角直徑
setMargins(const QMargins &margins) 設置圖表的外邊距
setTheme(QChart::ChartTheme theme) 設置圖表的主題

註意,上述表格中的方法並非 exhaustive,只是介紹了一些常見的和常用的方法。在實際使用中,可以根據需要查閱官方文檔獲取更詳細的信息。

1.1 繪製折線圖

接著我們來創建一個最基本的折線圖,首先需要使用圖形界面中的Graphics View組件做好UI佈局,但由於該組件並不是用於繪製圖形的,所以如果需要繪製圖形則要在組件上右鍵,選中提升為按鈕將其提升為繪圖組件,如下圖;

此時會彈出如下所示的提示框,我們直接輸入QChartView類名稱,並點擊添加按鈕,最後選擇提升按鈕,此時組件將將被支持繪製圖形;

為了能讓後續的代碼能夠更更容易的被讀著理解,此處還需要為讀者提供一份QGraphicsView組件的常用方法,如下表格是QGraphicsView的一些常用方法的概述:

方法 描述
QGraphicsView(QWidget *parent = nullptr) 預設構造函數,創建一個QGraphicsView對象。
setScene(QGraphicsScene *scene) 將指定的QGraphicsScene設置為視圖的場景。
scene() const 獲取當前視圖關聯的場景。
setRenderHint(QPainter::RenderHint hint, bool on = true) 設置渲染提示,例如抗鋸齒等。
setRenderHints(QPainter::RenderHints hints) 設置多個渲染提示。
renderHints() const 獲取當前的渲染提示。
setViewportUpdateMode(ViewportUpdateMode mode) 設置視口更新模式,決定何時重繪視口。
setSceneRect(const QRectF &rect) 設置場景矩形,指定在視圖中可見的場景區域。
setSceneRect(qreal x, qreal y, qreal w, qreal h) 設置場景矩形,指定在視圖中可見的場景區域。
sceneRect() const 獲取當前場景矩形。
setTransform(const QTransform &matrix, bool combine = false) 設置視圖的坐標變換矩陣。
resetTransform() 重置視圖的坐標變換矩陣為單位矩陣。
translate(qreal dx, qreal dy) 將視圖進行平移。
rotate(qreal angle) 將視圖進行旋轉。
scale(qreal sx, qreal sy) 將視圖進行縮放。
resetMatrix() 將視圖的坐標變換矩陣重置為單位矩陣。
setViewportMargins(int left, int top, int right, int bottom) 設置視口的邊緣,以保留用於顯示視圖的場景區域之外的空間。
setBackgroundBrush(const QBrush &brush) 設置視圖的背景刷。
viewport() const 獲取視口視窗部件,即視圖的直接子部件。
setOptimizationFlag(OptimizationFlag flag, bool enabled = true) 啟用或禁用指定的優化標誌,以提高性能。
optimizationFlag(OptimizationFlag flag) const 獲取指定的優化標誌狀態。
centerOn(const QGraphicsItem *item) 將視圖中心對準指定的圖形項。
centerOn(const QPointF &pos) 將視圖中心對準指定的場景坐標。
setInteractive(bool allowed) 啟用或禁用與場景中的項的交互。
setDragMode(DragMode mode) 設置拖動模式,用於選擇或移動項。
setViewportMargins(int left, int top, int right, int bottom) 設置視口的邊緣,以保留用於顯示視圖的場景區域之外的空間。
viewport() const 獲取視口視窗部件,即視圖的直接子部件。

這些方法提供了對QGraphicsView的各種設置和操作,用於管理視圖的外觀和行為。可以根據實際需要選擇適當的方法進行使用。

接著,我們來實現一個簡單的繪圖功能,在MainWindow構造函數中我們首先通過new QChart()創建一個圖表類,接著通過使用ui->graphicsView->setChart方法可以將QChart()類附加到QGraphicsView圖形組件上,當有了組件指針以後,就可以動態的通過折線圖的規則來創建圖例,當有了圖例以後則就可以通過series0->append()方法依次向圖形表格中追加記錄。

以下是對功能的概述:

  1. 創建圖表和序列:
    • 創建一個 QChart 對象,並設置圖表標題。
    • 將圖表添加到 QChartView 中,以便在UI中顯示。
    • 創建兩個曲線序列 QLineSeries,分別代表一分鐘和五分鐘的系統負載。
    • 將這兩個序列添加到圖表中。
  2. 設置圖表屬性:
    • 設置圖表的渲染提示,以提高圖表的渲染質量。
    • 設置圖表的主題色。
  3. 創建坐標軸:
    • 創建 X 軸和 Y 軸對象,並設置它們的範圍、標題、格式和刻度。
    • 為每個序列設置相應的坐標軸。
  4. 初始化數據:
    • 使用 QRandomGenerator 生成介於0和100之間的隨機整數,模擬系統負載的變化。
    • 將生成的隨機整數添加到兩個曲線序列中,分別對應一分鐘和五分鐘的負載。
    • 在X軸上遞增,以模擬時間的推移。
  5. 清空圖例和賦予數據:
    • 獲取序列的指針。
    • 清空曲線序列的數據,以便重新載入新的數據。
    • 通過迴圈生成的隨機數填充曲線序列。

總體來說,這段代碼創建了一個簡單的系統性能統計圖,其中包括兩條曲線,每條曲線代表不同時間段的系統負載。通過使用Qt Charts模塊,可以輕鬆創建並顯示這樣的圖表。

#include <QRandomGenerator>

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // ---------------------------------------------------
    // 創建圖表的各個部件
    // ---------------------------------------------------
    QChart *chart = new QChart();
    chart->setTitle("系統性能統計圖");

    // 將Chart添加到ChartView
    ui->graphicsView->setChart(chart);
    ui->graphicsView->setRenderHint(QPainter::Antialiasing);

    // 設置圖表主題色
    ui->graphicsView->chart()->setTheme(QChart::ChartTheme(0));

    // 創建曲線序列
    QLineSeries *series0 = new QLineSeries();
    QLineSeries *series1 = new QLineSeries();

    series0->setName("一分鐘負載");
    series1->setName("五分鐘負載");

    // 序列添加到圖表
    chart->addSeries(series0);
    chart->addSeries(series1);

    // 其他附加參數
    series0->setPointsVisible(false);       // 設置數據點可見
    series1->setPointLabelsVisible(false);  // 設置數據點數值可見

    // 創建坐標軸
    QValueAxis *axisX = new QValueAxis;    // X軸
    axisX->setRange(1, 100);               // 設置坐標軸範圍
    axisX->setTitleText("X軸標題");         // 標題
    axisX->setLabelFormat("%d %");         // 設置x軸格式
    axisX->setTickCount(3);                // 設置刻度
    axisX->setMinorTickCount(3);

    QValueAxis *axisY = new QValueAxis;    // Y軸
    axisY->setRange(0, 100);               // Y軸範圍(-0 - 20)
    axisY->setTitleText("Y軸標題");         // 標題
    axisY->setLabelFormat("%d %");         // 設置y軸格式
    axisY->setTickCount(3);                // 設置刻度
    axisY->setMinorTickCount(3);

    // 設置X於Y軸數據集
    chart->setAxisX(axisX, series0);   // 為序列設置坐標軸
    chart->setAxisY(axisY, series0);

    chart->setAxisX(axisX, series1);   // 為序列設置坐標軸
    chart->setAxisY(axisY, series1);

    // ---------------------------------------------------
    // 開始初始化數據
    // ---------------------------------------------------

    // 獲取指針
    series0=(QLineSeries *)ui->graphicsView->chart()->series().at(0);
    series1=(QLineSeries *)ui->graphicsView->chart()->series().at(1);

    // 清空圖例
    series0->clear();
    series1->clear();

    // 賦予數據
    qreal t=0,intv=1;
    for(int i=1;i<100;i++)
    {
        // 生成一個介於0和100之間的隨機整數
        int randomInt = QRandomGenerator::global()->bounded(101);
        int randomInt2 = QRandomGenerator::global()->bounded(84);

        series0->append(t,randomInt2);    // 設置軸粒度以及數據
        series1->append(t,randomInt);     // 此處用隨機數替代
        t+=intv;                          // X軸粒度
    }
}

當程式被編譯運行後,讀著可看到如下圖所示的模擬數據輸出;

1.2 繪製餅狀圖

接著來實現餅狀圖的繪製,此處我們增加兩個graphicsView組件來分別繪製兩個不同的餅狀圖,餅狀圖A用於統計CPU利用率,由於只有兩個數據集,所以只需要構建兩個QPieSlice即可,代碼如下所示;

void MainWindow::printA()
{
    // 構造數據 [已用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);

    // 將兩個餅狀分區加入series
    QPieSeries *series = new QPieSeries(this);
    series->append(slice_1);
    series->append(slice_2);

    // 創建Chart畫布
    QChart *chart = new QChart();
    chart->addSeries(series);

    // 設置顯示時的動畫效果
    chart->setAnimationOptions(QChart::AllAnimations);
    chart->setTitle("系統CPU利用率");

    // 將參數設置到畫布
    ui->graphicsView_A->setChart(chart);
    ui->graphicsView_A->setRenderHint(QPainter::Antialiasing);
    ui->graphicsView_A->chart()->setTheme(QChart::ChartTheme(0));
}

餅狀圖B的構建與A保持一致,只需要根據規則定義對圖表中的元素進行增減即可,但需要註意由於餅狀圖100%是最大值,所以再分配時需要考慮到配額的合理性。

void MainWindow::printB()
{
    // 構造數據 [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);

    // 將兩個餅狀分區加入series
    QPieSeries *series = new QPieSeries(this);
    series->append(slice_c);
    series->append(slice_d);
    series->append(slice_e);

    // 創建Chart畫布
    QChart *chart = new QChart();
    chart->addSeries(series);

    // 設置顯示時的動畫效果
    chart->setAnimationOptions(QChart::AllAnimations);
    chart->setTitle("系統磁碟信息");

    // 將參數設置到畫布
    ui->graphicsView_B->setChart(chart);
    ui->graphicsView_B->setRenderHint(QPainter::Antialiasing);

    // 設置不同的主題
    ui->graphicsView_B->chart()->setTheme(QChart::ChartTheme(3));
}

運行上述程式,則可以輸出兩個不同的餅狀圖,如下圖所示;

1.3 繪製柱狀圖

與餅狀圖的繪製方法一致,在繪製柱狀圖時只需要根據QBarSeries類的定義對特有元素進行填充即可,當數據集被填充後既可以直接調用繪圖方法將數據刷新到組件上。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 創建人名
    QBarSet *set0 = new QBarSet("張三");
    QBarSet *set1 = new QBarSet("李四");
    QBarSet *set2 = new QBarSet("王五");

    // 分別為不同人添加bu不同數據集
    *set0 << 1 << 2 << 8 << 4 << 6 << 6;
    *set1 << 5 << 2 << 5 << 4 << 5 << 3;
    *set2 << 5 << 5 << 8 << 15 << 9 << 5;

    // 將數據集關聯到series中
    QBarSeries *series = new QBarSeries();
    series->append(set0);
    series->append(set1);
    series->append(set2);

    // 增加頂部提示
    QChart *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("當前人數統計柱狀圖");
    chart->setAnimationOptions(QChart::SeriesAnimations);

    // 創建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);

    // 將參數設置到畫布
    ui->graphicsView->setChart(chart);
    ui->graphicsView->setRenderHint(QPainter::Antialiasing);

    // 設置主題
    ui->graphicsView->chart()->setTheme(QChart::ChartTheme(0));
}

運行代碼後則可以輸出如下圖所示的三個人的柱狀統計圖;

至此本章內容就結束了,通過本章內容讀著應該能掌握GraphicsView繪圖組件是如何提升的,並如何利用該組件實現簡單的繪製工作,從下一章開始我們將依次深入分析常用的圖形類,並實現一個更加實用的小功能,能夠讓讀者學以致用充分發揮Qt圖形組件的強大功能。

文章出處:https://www.cnblogs.com/LyShark/p/17922299.html
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ceph-deploy比較適合生產環境,不是用cephadm搭建。相對麻煩一些,但是並不難,細節把握好就行,只是命令多一些而已。 實驗環境 伺服器主機 public網段IP(對外服務) cluster網段IP(集群通信) 角色 deploy 192.168.2.120 用於部署集群、管理集群 cep ...
  • 在經濟社會發展的過程中,銀行的角色愈發重要。隨著金融體系不斷完善,各大銀行之間的交流、合作也變得尤為關鍵。而銀行之間互相識別和通信的一種方式,就是通過聯行號。 聯行號是指銀行間互相識別的一種編碼方式。每個銀行都擁有一個唯一的聯行號,用於區分不同的銀行和分行。有了聯行號,各大銀行之間的交流和轉賬操作就 ...
  • What is State 雖然數據流中的許多操作一次只查看一個單獨的事件(例如事件解析器),但某些操作會記住多個事件的信息(例如視窗運算元)。 這些操作稱為有狀態的(stateful)。 有狀態操作的一些示例: 當應用程式搜索某些事件模式(event patterns)時,狀態(state)將存儲迄 ...
  • 近日,天翼雲大數據平臺順利完成中國信通院無伺服器(Serverless) 架構大數據平臺測試,成為首批通過該測試的單位之一 ...
  • 1、首先選擇一張需要的圖片,通過左側的Resource Manage選擇“+”並選擇Import Drawables 選擇一張圖片 並調整以下兩個內容 這兩個內容的作用借用谷歌官方的Android開發教程的內容: *Android 設備具有不同的屏幕尺寸(手機、平板電腦和電視等),而且這些屏幕也具有 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1. 需求分析 實現一個CMS內容管理系統,在後臺進行內容編輯,在官網更新展示內容。 關於後臺的編輯功能,大致分為兩部分:組件拖拽預覽、組件內容編輯實時預覽。 對於組件拖拽預覽,用戶可以在含有各種功能組件的列表中,選擇需要的組件進行拖拽。 ...
  • | 當談到非同步編程時,async/await是JavaScript中常用的功能之一。下麵是10個常用的await和async函數示例,以及對它們的代碼用途的解析: 1.非同步獲取數據 async function fetchData() { const response = await fetch(' ...
  • 在前面隨筆《在Winform應用中增加通用的業務編碼規則生成》,我介紹了基於Winform和WPF的一個通用的業務編碼規則的管理功能,本篇隨筆介紹基於後端Web API介面,實現快速的Vue3+ElementPlus前端界面的開發整合,同樣是基於代碼生成工具實現快速的前端代碼的生成處理。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...