Qt編寫自定義控件48-面板窗體控件


一、前言

很多時候需要有一個控件,能夠替代容器控件,自動容納多個widget,自適應寬高,然后提供滾動條功能,這就必然需要用到QScrollArea控件,可設置各個子面板的間距等,也在很多系統中用到,比如溫濕度設備面板,有幾百個溫濕度設備,需要一個容器放置,自動產生滾動條,可以設置面板的固定寬高或者自適應拉伸,其實就是放了表格布局+彈簧來設置。
在后期的Qt內置控件的研究過程中,發現QListWidget也提供了類似的功能,所以后期有部分應用場景直接采用QListWidget來做。

二、實現的功能

  • 1:可設置標題欄文字/高度/字體/對齊方式/顏色
  • 2:可設置邊框寬度/邊框圓角角度/邊框顏色
  • 3:可設置報警顏色切換間隔/報警加深顏色/報警普通顏色
  • 4:可設置啟用狀態和禁用狀態時文字和邊框顏色

三、效果圖

四、頭文件代碼

#ifndef PANELFRAME_H
#define PANELFRAME_H

/**
 * 面板區域控件 作者:feiyangqingyun(QQ:517216493) 2017-10-21
 * 1:可設置標題欄文字/高度/字體/對齊方式/顏色
 * 2:可設置邊框寬度/邊框圓角角度/邊框顏色
 * 3:可設置報警顏色切換間隔/報警加深顏色/報警普通顏色
 * 4:可設置啟用狀態和禁用狀態時文字和邊框顏色
 */

#include <QWidget>

class QTimer;

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

class QDESIGNER_WIDGET_EXPORT PanelItem : public QWidget
#else
class PanelItem : public QWidget
#endif

{
    Q_OBJECT
    Q_ENUMS(Alignment)

    Q_PROPERTY(int titleHeight READ getTitleHeight WRITE setTitleHeight)
    Q_PROPERTY(QString titleText READ getTitleText WRITE setTitleText)
    Q_PROPERTY(QFont titleFont READ getTitleFont WRITE setTitleFont)
    Q_PROPERTY(Alignment titleAlignment READ getTitleAlignment WRITE setTitleAlignment)
    Q_PROPERTY(QColor titleColor READ getTitleColor WRITE setTitleColor)
    Q_PROPERTY(QColor titleDisableColor READ getTitleDisableColor WRITE setTitleDisableColor)

    Q_PROPERTY(int borderWidth READ getBorderWidth WRITE setBorderWidth)
    Q_PROPERTY(int borderRadius READ getBorderRadius WRITE setBorderRadius)
    Q_PROPERTY(QColor borderColor READ getBorderColor WRITE setBorderColor)
    Q_PROPERTY(QColor borderDisableColor READ getBorderDisableColor WRITE setBorderDisableColor)

    Q_PROPERTY(int alarmInterval READ getAlarmInterval WRITE setAlarmInterval)
    Q_PROPERTY(QColor alarmTextColor READ getAlarmTextColor WRITE setAlarmTextColor)
    Q_PROPERTY(QColor alarmDarkColor READ getAlarmDarkColor WRITE setAlarmDarkColor)
    Q_PROPERTY(QColor alarmNormalColor READ getAlarmNormalColor WRITE setAlarmNormalColor)

    Q_PROPERTY(bool isAlarm READ getIsAlarm WRITE setAlarm)
    Q_PROPERTY(bool isEnable READ getIsEnable WRITE setEnable)

public:
    enum Alignment {
        Alignment_Left = 0,     //左對齊
        Alignment_Center = 1,   //居中對齊
        Alignment_Right = 2     //右對齊
    };

    explicit PanelItem(QWidget *parent = 0);
    ~PanelItem();

protected:
    void paintEvent(QPaintEvent *);
    void drawBorder(QPainter *painter);
    void drawTitle(QPainter *painter);

private:
    int titleHeight;                //標題高度
    QString titleText;              //標題文字
    QFont titleFont;                //標題字體
    Alignment titleAlignment;       //標題對齊方式
    QColor titleColor;              //標題顏色
    QColor titleDisableColor;       //禁用狀態下文字顏色

    int borderWidth;                //邊框寬度
    int borderRadius;               //邊框圓角角度
    QColor borderColor;             //邊框顏色
    QColor borderDisableColor;      //禁用狀態下邊框顏色

    int alarmInterval;              //報警切換間隔
    QColor alarmTextColor;          //報警文字顏色
    QColor alarmDarkColor;          //報警加深顏色
    QColor alarmNormalColor;        //報警普通顏色

    bool isAlarm;                   //是否報警
    bool isEnable;                  //是否啟用

    bool isDark;                    //是否加深
    QColor tempColor;               //臨時顏色
    QTimer *timer;                  //報警切換定時器

public:
    int getTitleHeight()            const;
    QString getTitleText()          const;
    QFont getTitleFont()            const;
    Alignment getTitleAlignment()   const;
    QColor getTitleColor()          const;
    QColor getTitleDisableColor()   const;

    int getBorderWidth()            const;
    int getBorderRadius()           const;
    QColor getBorderColor()         const;
    QColor getBorderDisableColor()  const;

    int getAlarmInterval()          const;
    QColor getAlarmTextColor()      const;
    QColor getAlarmDarkColor()      const;
    QColor getAlarmNormalColor()    const;

    bool getIsAlarm()               const;
    bool getIsEnable()              const;

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

private slots:
    void checkAlarm();

public Q_SLOTS:
    //設置報警狀態
    void setAlarm(bool alarm);
    //設置啟用狀態
    void setEnable(bool enable);

    //設置標題欄高度
    void setTitleHeight(int titleHeight);
    //設置標題文字
    void setTitleText(const QString &titleText);
    //設置標題字體
    void setTitleFont(const QFont &titleFont);
    //設置標題文字對齊方式
    void setTitleAlignment(const Alignment &titleAlignment);
    //設置標題文字顏色
    void setTitleColor(const QColor &titleColor);
    //設置禁用狀態下標題文字顏色
    void setTitleDisableColor(const QColor &titleDisableColor);

    //設置邊框寬度
    void setBorderWidth(int borderWidth);
    //設置邊框圓角角度
    void setBorderRadius(int borderRadius);
    //設置邊框顏色
    void setBorderColor(const QColor &borderColor);
    //設置禁用狀態下邊框顏色
    void setBorderDisableColor(const QColor &borderDisableColor);

    //設置報警切換間隔
    void setAlarmInterval(int alarmInterval);
    //設置報警文字顏色
    void setAlarmTextColor(const QColor &alarmTextColor);
    //設置報警加深顏色
    void setAlarmDarkColor(const QColor &alarmDarkColor);
    //設置報警普通顏色
    void setAlarmNormalColor(const QColor &alarmNormalColor);

};

#endif // PANELFRAME_H


五、核心代碼

void PanelItem::paintEvent(QPaintEvent *)
{
    //繪制准備工作,啟用反鋸齒
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    //繪制邊框
    drawBorder(&painter);
    //繪制標題
    drawTitle(&painter);
}

void PanelItem::drawBorder(QPainter *painter)
{
    if (borderWidth <= 0) {
        return;
    }

    painter->save();

    QPen pen;
    pen.setWidth(borderWidth);
    pen.setColor(tempColor);

    painter->setPen(pen);
    painter->setBrush(Qt::NoBrush);
    QRect rect(borderWidth / 2, borderWidth / 2, width() - borderWidth, height() - borderWidth);
    painter->drawRoundedRect(rect, borderRadius, borderRadius);

    painter->restore();
}

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

    painter->setPen(Qt::NoPen);
    painter->setBrush(tempColor);

    int offset = borderWidth - borderWidth / 3;
    QRect rect(offset, offset, width() - offset * 2, titleHeight);
    painter->drawRect(rect);

    //繪制標題文字
    if (isEnable) {
        painter->setPen(isAlarm ? alarmTextColor : titleColor);
    } else {
        painter->setPen(titleDisableColor);
    }

    painter->setFont(titleFont);

    //文字區域要重新計算
    offset = borderWidth * 3;
    QRect textRect(offset, 0, width() - offset * 2, titleHeight);

    Qt::Alignment align;
    if (titleAlignment == Alignment_Left) {
        align = Qt::AlignLeft | Qt::AlignVCenter;
    } else if (titleAlignment == Alignment_Center) {
        align = Qt::AlignHCenter | Qt::AlignVCenter;
    } else if (titleAlignment == Alignment_Right) {
        align = Qt::AlignRight | Qt::AlignVCenter;
    }

    painter->drawText(textRect, align, titleText);

    painter->restore();
}

六、控件介紹

  1. 超過150個精美控件,涵蓋了各種儀表盤、進度條、進度球、指南針、曲線圖、標尺、溫度計、導航條、導航欄,flatui、高亮按鈕、滑動選擇器、農歷等。遠超qwt集成的控件數量。
  2. 每個類都可以獨立成一個單獨的控件,零耦合,每個控件一個頭文件和一個實現文件,不依賴其他文件,方便單個控件以源碼形式集成到項目中,較少代碼量。qwt的控件類環環相扣,高度耦合,想要使用其中一個控件,必須包含所有的代碼。
  3. 全部純Qt編寫,QWidget+QPainter繪制,支持Qt4.6到Qt5.12的任何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. 目前已提供26個版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。
  17. 不定期增加控件和完善控件,不定期更新SDK,歡迎各位提出建議,謝謝!
  18. Qt入門書籍推薦霍亞飛的《Qt Creator快速入門》《Qt5編程入門》,Qt進階書籍推薦官方的《C++ GUI Qt4編程》。
  19. 強烈推薦程序員自我修養和規划系列書《大話程序員》《程序員的成長課》《解憂程序員》,受益匪淺,受益終生!
  20. SDK下載鏈接:https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ 提取碼:877p
  21. 下載鏈接中包含了各個版本的動態庫文件,所有控件的頭文件,使用demo,自定義控件+屬性設計器。
  22. widget版本(QQ:517216493)qml版本(QQ:373955953)三峰駝(QQ:278969898)。
  23. 濤哥的知乎專欄 Qt進階之路 https://zhuanlan.zhihu.com/TaoQt
  24. 歡迎關注微信公眾號【高效程序員】,C++/Python、學習方法、寫作技巧、熱門技術、職場發展等內容,干貨多多,福利多多!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM