自定义圆形进度条控件

以下将以创建一个简单的为例,详细说明在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%,并将控件移动到主窗口内的指定位置。最后设置了主窗口的固定大小。

通过以上步骤,我们成功创建了一个简单的自定义圆形进度条控件,并在主窗口中进行了使用。你可以根据实际需求进一步扩展和完善这个自定义控件的功能,比如添加动画效果、响应鼠标事件等。

posted @ 2024-11-10 16:01  MarsCactus  阅读(52)  评论(0编辑  收藏  举报