Qt編寫自定義控件64-垂直時間軸

1、前言

垂直時間軸控件,主要用來描述企業發展歷程大事件,或者軟件版本迭代歷史等,經過時間節點和事件描述來直觀的展現發展的過程,通常在web網頁或者app中常常看到此類控件,尤爲是公司的官網關於公司部分,着重在一些獨角獸公司或者正處於蓬勃發展的公司,用來展現本身多牛逼,發展多麼迅猛等。 垂直時間軸控件主要存儲的數據包含兩個,一個是時間節點,一個是事件描述,爲了後期的拓展性,採用結構體來存放這個數據,好比後期還可能增長該事件是否屬於大事件標記,是的話則繪製的時候突出顯示好比加大字號加粗,本控件的主要難點在於自動計算和排列來繪製時間和事件描述,默認採用對等分的機制來處理繪製,還有部分時間軸控件是左側時間右側事件描述,這個能夠在源碼基礎上自行更改或者增長樣式,爲了可以展現全部的事件,本控件主體是繼承自滾動條區域控件,超太高度自動產生滾動條。linux

2、實現的功能

  • 1:可設置節點邊距
  • 2:可設置節點高度
  • 3:可設置信息邊框邊距
  • 4:可設置信息所佔高度
  • 5:可設置基準顏色/線條顏色
  • 6:可設置標題/信息集合
  • 7:自動產生滾動條
  • 8:支持字符串形式設置數據

3、效果圖

4、頭文件代碼

#ifndef TIMEAXIS_H
#define TIMEAXIS_H

/**
 * 垂直時間軸控件 做者:雨田哥(QQ:3246214072) 整理:feiyangqingyun(QQ:517216493) 2019-10-07
 * 1:可設置節點邊距
 * 2:可設置節點高度
 * 3:可設置信息邊框邊距
 * 4:可設置信息所佔高度
 * 5:可設置基準顏色/線條顏色
 * 6:可設置標題/信息集合
 * 7:自動產生滾動條
 * 8:支持字符串形式設置數據
 */

#include <QScrollArea>
class TimeAxisWidget;

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT TimeAxis : public QScrollArea
#else
class TimeAxis : public QScrollArea
#endif

{
    Q_OBJECT
    Q_PROPERTY(int itemMargin READ getItemMargin WRITE setItemMargin)
    Q_PROPERTY(int itemHeight READ getItemHeight WRITE setItemHeight)
    Q_PROPERTY(int infoPadding READ getInfoPadding WRITE setInfoPadding)
    Q_PROPERTY(int infoHeight READ getInfoHeight WRITE setInfoHeight)

    Q_PROPERTY(QColor baseColor READ getBaseColor WRITE setBaseColor)
    Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor)

    Q_PROPERTY(QString title READ getTitle WRITE setTitle)
    Q_PROPERTY(QString infos READ getInfos WRITE setInfos)

public:
    explicit TimeAxis(QWidget *parent = 0);

private:
    int itemMargin;         //節點邊距
    int itemHeight;         //節點高度
    int infoPadding;        //信息邊距
    int infoHeight;         //信息高度

    QColor baseColor;       //基準顏色
    QColor lineColor;       //線條顏色

    QString title;          //標題
    QString infos;          //信息集合

    //時間軸主控件
    TimeAxisWidget *timeAxisWidget;

public:
    int getItemMargin()     const;
    int getItemHeight()     const;
    int getInfoPadding()    const;
    int getInfoHeight()     const;

    QColor getBaseColor()   const;
    QColor getLineColor()   const;

    QString getTitle()      const;
    QString getInfos()      const;

    QSize sizeHint()        const;
    QSize minimumSizeHint() const;

    TimeAxisWidget *getWidget();

public Q_SLOTS:
    //設置節點邊距+節點高度
    void setItemMargin(int itemMargin);
    void setItemHeight(int itemHeight);

    //設置信息邊距+信息高度
    void setInfoPadding(int infoPadding);
    void setInfoHeight(int infoHeight);

    //設置基準顏色+線條顏色
    void setBaseColor(const QColor &baseColor);
    void setLineColor(const QColor &lineColor);

    //設置標題+信息集合
    void setTitle(const QString &title);
    void setInfos(const QString &infos);
};

class TimeAxisWidget : public QWidget
{
    Q_OBJECT

public:
    //能夠自行拓展其餘信息
    struct TimeAxisInfo {
        QString time;   //時間
        QString info;   //信息
    };

    explicit TimeAxisWidget(QWidget *parent = 0);

protected:
    void paintEvent(QPaintEvent *);
    void drawTitle(QPainter *painter);
    void drawLine(QPainter *painter);
    void drawInfo(QPainter *painter);
    void drawInfoRight(QPainter *painter, const QRectF &infoRect, int infoHeight);
    void drawInfoLeft(QPainter *painter, const QRectF &infoRect, int infoHeight);

private:
    int itemMargin;         //節點邊距
    int itemHeight;         //節點高度
    int infoPadding;        //信息邊距
    int infoHeight;         //信息高度

    QColor baseColor;       //基準顏色
    QColor lineColor;       //線條顏色

    QString title;          //標題
    QString infos;          //信息集合

    //信息集合結構體
    QList<TimeAxisInfo> itemInfos;

public:
    int getItemMargin()     const;
    int getItemHeight()     const;
    int getInfoPadding()    const;
    int getInfoHeight()     const;

    QColor getBaseColor()   const;
    QColor getLineColor()   const;

    QString getTitle()      const;
    QString getInfos()      const;

    QSize sizeHint()        const;
    QSize minimumSizeHint() const;

public Q_SLOTS:
    //設置節點邊距+節點高度
    void setItemMargin(int itemMargin);
    void setItemHeight(int itemHeight);

    //設置信息邊距+信息高度
    void setInfoPadding(int infoPadding);
    void setInfoHeight(int infoHeight);

    //設置基準顏色+線條顏色
    void setBaseColor(const QColor &baseColor);
    void setLineColor(const QColor &lineColor);

    //設置標題+信息集合
    void setTitle(const QString &title);
    void setInfos(const QString &infos);

    //設置信息集合,結構體方式
    void setItemInfos(const QList<TimeAxisInfo> &itemInfos);
};

#endif // TIMEAXIS_H

5、核心代碼

void TimeAxisWidget::drawTitle(QPainter *painter)
{
    painter->save();

    QFont font;
    font.setBold(true);
    font.setPointSize(16);
    painter->setFont(font);

    painter->setPen(baseColor);
    painter->drawText(itemMargin, itemMargin, width() - 2 * itemMargin, 40, Qt::AlignCenter, title);

    painter->restore();
}

void TimeAxisWidget::drawLine(QPainter *painter)
{
    painter->save();
    painter->setPen(QPen(lineColor, 6));
    int startY = itemMargin + 50;
    int endY = startY + itemInfos.size() * itemHeight;
    painter->drawLine(width() / 2.0, startY, width() / 2.0, endY);
    painter->restore();

    //設置下固定高度
    this->setFixedHeight(endY + itemMargin);
}

void TimeAxisWidget::drawInfo(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);

    QFont font;
    font.setPointSize(12);
    painter->setFont(font);

    int startY = itemMargin + 50;
    int centerX = this->width() / 2.0;
    int spacer = itemMargin + 10;

    //追個繪製時間軸信息集合,偶數行左側繪製時間右側繪製信息
    for (int i = 0; i < itemInfos.size(); i++) {
        painter->setBrush(Qt::white);
        painter->setPen(QPen(baseColor, 2));

        if (i % 2 == 0) {
            //繪製時間
            QRectF textRect(0, startY, centerX - spacer, itemHeight);
            painter->drawText(textRect, Qt::AlignRight | Qt::AlignVCenter, itemInfos.at(i).time);
            //繪製信息邊框
            QRectF infoRect(centerX + spacer, textRect.center().y() - infoHeight / 2.0, centerX - spacer - itemMargin - infoHeight / 2.0, infoHeight);
            drawInfoRight(painter, infoRect, infoHeight);
            //繪製信息背景
            painter->setBrush(baseColor);
            drawInfoRight(painter, infoRect.adjusted(infoPadding, infoPadding, 0, -infoPadding), infoHeight - infoPadding * 2);
            //繪製信息文字
            painter->setPen(Qt::white);
            painter->drawText(infoRect.adjusted(infoPadding, infoPadding, 0, -infoPadding), Qt::AlignCenter, itemInfos.at(i).info);
        } else {
            //繪製時間
            QRectF textRect(centerX + spacer, startY, centerX - spacer, itemHeight);
            painter->drawText(centerX + spacer, startY, centerX - spacer, itemHeight, Qt::AlignLeft | Qt::AlignVCenter, itemInfos.at(i).time);
            //繪製信息邊框
            QRectF infoRect(itemMargin + infoHeight / 2.0, textRect.center().y() - infoHeight / 2.0, centerX - spacer - itemMargin - infoHeight / 2.0, infoHeight);
            drawInfoLeft(painter, infoRect, infoHeight);
            //繪製信息背景
            painter->setBrush(baseColor);
            drawInfoLeft(painter, infoRect.adjusted(0, infoPadding, -infoPadding, -infoPadding), infoHeight - infoPadding * 2);
            //繪製信息文字
            painter->setPen(Qt::white);
            painter->drawText(infoRect.adjusted(0, infoPadding, -infoPadding, -infoPadding), Qt::AlignCenter, itemInfos.at(i).info);
        }

        //繪製垂直線對應的圓
        painter->setPen(Qt::NoPen);
        painter->setBrush(baseColor);
        painter->drawEllipse(centerX - 8, startY + itemHeight / 2.0 - 8, 16, 16);
        painter->setBrush(Qt::white);
        painter->drawEllipse(centerX - 4, startY + itemHeight / 2.0 - 4, 8, 8);

        //Y軸往下移一個高度
        startY += itemHeight;
    }

    painter->restore();
}

6、控件介紹

  1. 超過160個精美控件,涵蓋了各類儀表盤、進度條、進度球、指南針、曲線圖、標尺、溫度計、導航條、導航欄,flatui、高亮按鈕、滑動選擇器、農曆等。遠超qwt集成的控件數量。
  2. 每一個類均可以獨立成一個單獨的控件,零耦合,每一個控件一個頭文件和一個實現文件,不依賴其餘文件,方便單個控件以源碼形式集成到項目中,較少代碼量。qwt的控件類環環相扣,高度耦合,想要使用其中一個控件,必須包含全部的代碼。
  3. 所有純Qt編寫,QWidget+QPainter繪製,支持Qt4.6到Qt5.13的任何Qt版本,支持mingw、msvc、gcc等編譯器,支持任意操做系統好比windows+linux+mac+嵌入式linux等,不亂碼,可直接集成到Qt Creator中,和自帶的控件同樣使用,大部分效果只要設置幾個屬性便可,極爲方便。
  4. 每一個控件都有一個對應的單獨的包含該控件源碼的DEMO,方便參考使用。同時還提供一個全部控件使用的集成的DEMO。
  5. 每一個控件的源代碼都有詳細中文註釋,都按照統一設計規範編寫,方便學習自定義控件的編寫。
  6. 每一個控件默認配色和demo對應的配色都很是精美。
  7. 超過130個可見控件,6個不可見控件。
  8. 部分控件提供多種樣式風格選擇,多種指示器樣式選擇。
  9. 全部控件自適應窗體拉伸變化。
  10. 集成自定義控件屬性設計器,支持拖曳設計,所見即所得,支持導入導出xml格式。
  11. 自帶activex控件demo,全部控件能夠直接運行在ie瀏覽器中。
  12. 集成fontawesome圖形字體+阿里巴巴iconfont收藏的幾百個圖形字體,享受圖形字體帶來的樂趣。
  13. 全部控件最後生成一個動態庫文件(dll或者so等),能夠直接集成到qtcreator中拖曳設計使用。
  14. 目前已經有qml版本,後期會考慮出pyqt版本,若是用戶需求量很大的話。
  15. 自定義控件插件開放動態庫使用(永久免費),無任何後門和限制,請放心使用。
  16. 目前已提供32個版本的dll,其中qt_5_7_0_mingw530_32這個版本會一直保證最新的完整的。
  17. 不按期增長控件和完善控件,不按期更新SDK,歡迎各位提出建議,謝謝!
  18. Qt入門書籍推薦霍亞飛的《Qt Creator快速入門》《Qt5編程入門》,Qt進階書籍推薦官方的《C++ GUI Qt4編程》。
  19. 強烈推薦程序員自我修養和規劃系列書《大話程序員》《程序員的成長課》《解憂程序員》,受益不淺,受益終生!
  20. SDK地址:https://gitee.com/feiyangqingyun/QUCSDK https://github.com/feiyangqingyun/qucsdk
相關文章
相關標籤/搜索