自定義圓形進度條控制元件

MarsCactus發表於2024-11-10

以下將以建立一個簡單的為例,詳細說明在Qt中建立自定義控制元件的步驟:

一、建立專案

首先,開啟Qt Creator並建立一個新的Qt Widgets Application專案。按照嚮導完成專案的基本設定,比如專案名稱、儲存路徑等。

二、建立自定義控制元件類

  1. 繼承基礎控制元件類
    • 在專案中建立一個新的C++類,命名為 CircleProgressBar。讓這個類繼承自 QWidget,因為我們要建立一個獨立的視覺化控制元件,QWidget 是Qt中大多數視覺化控制元件的基類。
#include <QWidget>

class CircleProgressBar : public QWidget
{
    Q_OBJECT
public:
    explicit CircleProgressBar(QWidget *parent = nullptr);

signals:

public slots:

private:

};
  1. 新增建構函式
    • CircleProgressBar 類中新增建構函式,用於初始化控制元件的一些基本屬性,如大小、顏色等。
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>

class CircleProgressBar : public QWidget
{
    Q_OBJECT
public:
    explicit CircleProgressBar(QWidget *parent = nullptr) : QWidget(parent)
    {
        setFixedSize(200, 200); // 設定控制元件的固定大小為直徑200畫素的圓形
        progress = 0; // 初始進度為0
        backgroundColor = Qt::lightGray; // 設定背景顏色為淺灰色
        progressColor = Qt::blue; // 設定進度條顏色為藍色
    }

signals:

public slots:

private:
    int progress;
    QColor backgroundColor;
    QColor progressColor;
};

在上述建構函式中,透過呼叫 setFixedSize 函式設定了控制元件的大小為一個直徑200畫素的圓形。同時,初始化了進度值為0,並設定了背景顏色和進度條顏色。

三、重寫繪製事件函式

為了能夠在控制元件上繪製出圓形進度條的外觀,需要重寫 QWidgetpaintEvent 函式,在該函式中使用 QPainter 類來進行繪製操作。

#include <QWidget>
#include <QPainter>
#include <QPaintEvent>

class CircleProgressBar : public QWidget
{
    Q_OBJECT
public:
    explicit CircleProgressBar(QWidget *parent = nullptr) : QWidget(parent)
    {
        setFixedSize(200, 200);
        progress = 0;
        backgroundColor = Qt::lightGray;
        progressColor = Qt::blue;
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        Q_UNUSED(event);
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing); // 開啟抗鋸齒,使繪製的圖形更平滑

        // 繪製背景圓形
        painter.setPen(Qt::NoPen);
        painter.setBrush(backgroundColor);
        painter.drawEllipse(rect());

        // 繪製進度條圓形
        painter.setPen(Qt::NoPen);
        painter.setBrush(progressColor);
        int arcLength = (progress / 100.0) * 360 * 16; // 根據進度計算弧長,乘以16是因為QPainter繪製弧形的單位要求
        painter.drawArc(rect(), 90 * 16, arcLength);
    }

signals:

public slots:

private:
    int progress;
    QColor backgroundColor;
    QColor progressColor;
};

paintEvent 函式中:

  • 首先建立了一個 QPainter 物件,並開啟了抗鋸齒功能,以獲得更平滑的繪製效果。
  • 然後使用 QPainter 繪製了背景圓形,透過設定畫筆為 Qt::NoPen(即不繪製輪廓線),設定畫刷為背景顏色,再使用 drawEllipse 函式根據控制元件的矩形區域(透過 rect() 函式獲取)繪製出背景圓形。
  • 接著繪製進度條圓形,同樣設定畫筆為 Qt::NoPen,畫刷為進度條顏色,根據當前進度計算出弧長,再使用 drawArc 函式在背景圓形上繪製出進度條弧形。

四、新增設定進度的函式

為了能夠在外部方便地設定圓形進度條的進度值,需要新增一個公共函式來實現此功能。

#include <QWidget>
#include <QPainter>
#include <QPaintEvent>

class CircleProgressBar : public QWidget
{
    Q_OBJECT
public:
    explicit CircleProgressBar(QWidget *parent = nullptr) : QWidget(parent)
    {
        setFixedSize(200, 200);
        progress = 0;
        backgroundColor = Qt::lightGray;
        progressColor = Qt::blue;
    }

    void setProgress(int value)
    {
        progress = value;
        update(); // 更新控制元件的顯示,以便重新繪製進度條
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        Q_UNUSED(event);
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);

        // 繪製背景圓形
        painter.setPen(Qt::NoPen);
        painter.setBrush(backgroundColor);
        painter.drawEllipse(rect());

        // 繪製進度條圓形
        painter.setPen(Qt::NoPen);
        painter.setBrush(progressColor);
        int arcLength = (progress / 100.0) * 360 * 16;
        painter.drawArc(rect(), 90 * 16, arcLength);
    }

signals:

public slots:

private:
    int progress;
    QColor backgroundColor;
    QColor progressColor;
};

setProgress 函式中,首先更新了內部的進度值變數,然後呼叫 update() 函式,該函式會觸發 paintEvent 函式的重新執行,從而根據新的進度值重新繪製進度條。

五、在主視窗中使用自定義控制元件

  1. 包含標頭檔案
    • 在主視窗的標頭檔案(通常是 mainwindow.h)中,包含自定義控制元件類的標頭檔案。
#include <QMainWindow>
#include "CircleProgressBar.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    CircleProgressBar *circleProgressBar;
};
  1. 建立並設定自定義控制元件
    • 在主視窗的建構函式中,建立自定義控制元件物件,並設定其在主視窗中的位置等屬性。
#include <QMainWindow>
#include "CircleProgressBar.h"

MainWindow::MainWindow(QWidget *parent = nullptr) : QMainWindow(parent)
{
    circleProgressBar = new CircleProgressBar(this);
    circleProgressBar->setProgress(50); // 設定初始進度為50%
    circleProgressBar->move(50, 50); // 將控制元件移動到主視窗的指定位置

    setFixedSize(300, 300); // 設定主視窗的固定大小
}

MainWindow::~MainWindow()
{
    delete circleProgressBar;
}

在上述主視窗的建構函式中,首先建立了 CircleProgressBar 控制元件物件,並將其所屬的父控制元件設定為當前主視窗。然後設定了初始進度為50%,並將控制元件移動到主視窗內的指定位置。最後設定了主視窗的固定大小。

透過以上步驟,我們成功建立了一個簡單的自定義圓形進度條控制元件,並在主視窗中進行了使用。你可以根據實際需求進一步擴充套件和完善這個自定義控制元件的功能,比如新增動畫效果、響應滑鼠事件等。

相關文章