Qt高级--(1)自定义导航栏

本文介绍了使用Qt开发自定义导航栏的方法。阐述了如何分析需求,包括布局(图标、文字、背景颜色等)和状态(正常、鼠标悬停、鼠标选中),还讲解了Q_PROPERTY属性的使用,最后给出了相关源代码文件,如.pro、.h、.cpp和.ui文件。

好久没有水博客,参考别人的写一个自定义的导航栏吧。用处挺多的,可以用来切换到不同的信息显示界面。

功能点

1.默认情况下,文字居中显示,不显示图标,不显示三角。
2.可设置文字左侧、顶部、右侧、底部边距;可设置文字对齐方式。
3.可设置图标是否显示、一侧边距、图标大小、显示位置。
4可设置三角是否显示、大小、显示位置,三角值设置了鼠标悬停和鼠标选中状态下显示。
5.可设置背景颜色为画刷颜色。
6.可设置文字与图标的相对位置:图标左文字右、图标右文字左、图标上文字下、图标下文字上。
7.按钮状态分为三种:正常、鼠标悬停、鼠标选中。
8.在按钮不同状态下可设置不同的背景颜色、字体颜色、图标切换、三角颜色等。
9.一组导航按钮一次只能选中一个。
在这里插入图片描述

一、如何分析自己的需求:

布局

1.我这个类是要显示出,界面上的控件,显示的图标,文字(大小,颜色)。
2.除了显示的,还有图标文字之间的布局,还有背景颜色。

从上面看出显示上的主要有,图标文字,布局,背景颜色。
文字
最简单的一种情况是,一个导航按钮只有文字,没有图标。如下图所示,需要考虑到文字到四边的边距、颜色、背景颜色等。
文字距四边的边距分别使用一个变量来保存,在绘制文本时需要将边距计算在内。
在这里插入图片描述
图标 + 文字
当在文字的基础上加上图标时需要增加属性,并且在计算边距时需要将图标考虑在内。
在计算图标与文字的相对位置时需要注意图标的边距与文字的同边边距是重叠的。如下图中图标边距是距离左侧的边距,文字的左边距是包含了图标边距。
此时需要计算图标的大小,同时还需要考虑图标与文字的相对位置,即图标在左文字在右、图标在右文字在左、图标在上文字在下、图标在下文字在上。
在以上的可能性中,图标在左文字在右、图标在上文字在下这两种方式是常用的。
图标与文字左右结构:

在这里插入图片描述

图标与文字上下结构:
在这里插入图片描述

图标 + 文字 + 三角
在 图标 + 文字的基础上增加三角,多个导航按钮组合时可能会达到更好的效果。
在画三角时可以不考虑边距的文字,只需要考虑三角的方向、颜色。
在这里插入图片描述
从上面看出,我们需要定义的变量就有:

//布局限制位置
    int m_paddingLeft;                  // 文字左侧间距
    int m_paddingTop;                   // 文字顶部间距
    int m_paddingRight;                 // 文字右侧间距
    int m_paddingBottom;                // 文字底部间距
    //文字(大小,颜色,对齐方式)
    TextAlign m_textAlign;              // 文字对齐方式,TextAlign对齐样式 
    QColor m_nTextColor;                // 正常文字颜色
    QColor m_hTextColor;                // 悬停文字颜色
    QColor m_cTextColor;                // 选中文字颜色
    QPen m_textPen;                     // 文字大小、颜色
    //背景
    QBrush m_nBgBrush;                  // 正常背景画刷
    QBrush m_hBgBrush;                  // 悬停背景画刷
    QBrush m_cBgBrush;                  // 选中背景画刷
    QColor m_nBgColor;                  // 正常背景颜色
    QColor m_hBgColor;                  // 悬停背景颜色
    QColor m_cBgColor;                  // 选中背景颜色
    //图标()
    bool m_showIcon;                    // 显示图标
    int m_iconSpace;                    // 图标边距,左边显示图标是距离左边边距,顶部显示图标表示距离顶部边距,以此类推
    QSize m_iconSize;                   // 图标尺寸
    QPixmap m_nIcon;                    // 正常图标
    QPixmap m_hIcon;                    // 悬停图标
    QPixmap m_cIcon;                    // 选中图标
    IconPosition m_iconPos;             // 图标显示位置
    //三角
    bool m_showTriangle;                // 是否显示三角
    int m_triSideLength;                // 三角形边长
    TrianglePosition m_triPos;          // 三角形显示位置
    QColor m_triColor;                  // 三角形显示颜色

总结:如果是可以有的,也可以没有的,增加一个bool来控制是否显示。

状态

1.在设计的导航按钮中使用三种状态:正常、鼠标悬停、鼠标选中。
2.文字颜色在三种状态下颜色不同,需要使用三个颜色变量分别保存三种状态下的颜色值。
3.背景颜色在三种状态下颜色不同,需要使用三个颜色变量分别保存三种状态下的颜色值。
4.继承 enterEvent 和 leaveEvent 事件函数来判断鼠标上划状态。

bool m_hover;                       // 鼠标悬停标志
//不需要选中状态,因为,可以根据QpushButton来获取是否是点击状态

总结:我们只要知道一些布局和行为就可以定出所有的变量出来。

Q_PROPERTY 属性

Q_PROPERTY 是 Qt 中的一个宏,是用类中声明属性。如果需要使用该宏,必须要继承 QObject 类或者其子类。QPushButton 则是 QObject 的间接子类,所以继承 QPushButton 类后同样可以使用 Q_PROPERTY 宏。

Q_PROPERTY 属性自带了一些属性,同样程序可以自定义。本实验中只讲解 Q_PROPERTY 自带的属性。

在自定义导航按钮的程序中同样使用了 Q_PROPERTY,且程序中只使用了 Q_PROPERTY 的 READ 属性和 WRITE 属性。

class JNaviButton : public QPushButton
{
   
   
    Q_PROPERTY(int m_paddingLeft READ paddingLeft WRITE setPaddingLeft)
    Q_PROPERTY(int m_paddingTop READ paddingTop WRITE setPaddingTop)
    Q_PROPERTY(int m_paddingRight READ paddingRight WRITE setPaddingRight)
    Q_PROPERTY(int m_paddingBottom READ paddingBottom WRITE setPaddingBottom)
    // ...
}

Q_PROPERTY 自带属性:

Q_PROPERTY(type name
           READ getFunction
           [WRITE setFunction]
           [RESET resetFunction]
           [NOTIFY notifySignal]
           [DESIGNABLE bool]
           [SCRIPTABLE bool]
           [STORED bool]
           [USER bool]
           [CONSTANT]
           [FINAL])

在上面的代码中,方括号 [] 中的内容属性可选。
必选 READ 属性:用来读取属性值,因此使用 const 限制,返回值类型必须为属性类型或者属性类型的引用或者指针。
可选 WRITE 属性:用来设置属性值,返回值必须为 void 类型,需要一个参数。
可选 RESET 属性:能够将值设置为默认状态,返回值为 void 类型且不带参数。
可选 NOTIFY 属性:提供一个信号,当值发送改变是该信号会自动被触发。
可选 DESIGNABLE 属性:是否在界面设计器的属性编辑器中出现。大多数属性是可见的,除了可以为变量传入 true 或 false 还可以执行一个 bool 行的成员函数。
可选 SCRIPTABLE 属性:是够可以被脚本引擎操作(默认为 true)。可以赋予 true 或者 false 或 bool 类型的函数。
可选 STORED 属性:是否被认为是独立存在还是依赖于其他的值而存在,也可以表明是否在保存对象状态时保存此属性的值。大多数属性都是需要保存的,但也有例外,例如 QWidget::minimumWidth() 就是不被保存的,因为它的值是从另一个属性 QWidget::minimumSize() 得来的。
可选 USER 属性:是否被设计为面向用户的或用户可修改的类属性。通常,每个类只有一个 USER 属性。例如 QAbstractButton::checked 是按钮类的用户可修改属性。注意 QItemDelegate 获取和设置 widget 的 USER 属性。
可选 CONSTANT 属性:表示属性的值是不变的。
可选 FINAL 属性:表示属性不能被派生类所重写。

源代码:

.pro

#-------------------------------------------------
#
# Project created by QtCreator 2020-06-30T08:24:07
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = 3-1-JNaviButton
TEMPLATE = app


SOURCES += main.cpp\
        widget.cpp \
    jnavibutton.cpp

HEADERS  += widget.h \
    jnavibutton.h

FORMS    += widget.ui

RESOURCES += \
    source.qrc

JNaviButton .h

#ifndef JNAVIBUTTON_H
#define JNAVIBUTTON_H

/**
  该导航按钮参考了 feiyangqingyun 的导航按钮类
 */
/** 功能
 * 1. 默认情况下,文字居中显示,不显示图标,不显示三角
 * 2. 可设置文字左侧、顶部、右侧、底部编剧;可设置文字显示对其方式
 * 3. 可设置图标是否显示、一侧边距、图标大小、显示位置
 * 4. 可设置三角是否显示、大小、显示位置,三角只设置了鼠标悬停和鼠标选中状态下显示
 * 5. 可设置北京颜色为画刷颜色
 * 6. 可设置文字与图标的相对位置:图标左文字右、图标右文字左、图标上文字下、图标下文字上
 * 7. 按钮状态分为三种:正常、鼠标悬停、鼠标选中
 * 8. 在按钮不同状态下可设置不同的背景颜色、字体颜色、图标切换、三角颜色等
 * 9. 一组导航按钮一次只能选中一个
 */

#include <QPushButton>
#include <QPainter>

class JNaviButton : public QPushButton
{
   
   
    Q_OBJECT
    Q_ENUMS(TextAlign)
    Q_ENUMS(IconPosition)

    Q_PROPERTY(int m_paddingLeft READ paddingLeft WRITE setPaddingLeft)
    Q_PROPERTY(int m_paddingTop READ paddingTop WRITE setPaddingTop)
    Q_PROPERTY(int m_paddingRight READ paddingRight WRITE setPaddingRight)
    Q_PROPERTY(int m_paddingBottom READ paddingBottom WRITE setPaddingBottom)
    Q_PROPERTY(TextAlign m_textAlign READ textAlign WRITE setTextAlign)
    Q_PROPERTY(QColor m_nTextColor READ normalTextColor WRITE setNormalTextColor)
    Q_PROPERTY(QColor m_hTextColor READ hoverTextColor WRITE setHoverTextColor)
    Q_PROPERTY(QColor m_cTextColor READ checkedTextColor WRITE setCheckedTextColor)
    Q_PROPERTY(QPen m_textPen READ textPen WRITE setTextPen)

    Q_PROPERTY(QBrush m_nBgBrush READ normalBgBrush WRITE setNormalBgBrush)
    Q_PROPERTY(QBrush m_hBgBrush READ hoverBgBrush WRITE setHoverBgBrush)
    Q_PROPERTY(QBrush m_cBgBrush READ checkedBgBrush WRITE setCheckedBgBrush)

    Q_PROPERTY(QColor m_nBgColor READ normalBgColor WRITE setNormalBgColor)
    Q_PROPERTY(QColor m_hBgColor READ hoverBgColor WRITE setHoverBgColor)
    Q_PROPERTY(QColor m_cBgColor READ checkedBgColor WRITE setCheckedBgColor)

    Q_PROPERTY(bool m_showIcon READ showIcon WRITE setShowIcon)
    Q_PROPERTY(int  m_iconSpace READ iconSpace WRITE setIconSpace)
    Q_PROPERTY(QSize m_iconSize READ iconSize WRITE setIconSize)
    Q_PROPERTY(QPixmap m_nIcon READ normalIcon WRITE setNormalIcon)
    Q_PROPERTY(QPixmap m_hIcon READ hoverIcon WRITE setHoverIcon)
    Q_PROPERTY(QPixmap m_cIcon READ checkedIcon WRITE setCheckedIcon)
    Q_PROPERTY(IconPosition m_iconPos READ iconPosition WRITE setIconPosition)

    Q_PROPERTY(bool m_showTriangle READ showTriabgle WRITE setShowTriangle)
    Q_PROPERTY(int m_triSideLength READ triangleSideLength WRITE setTriangleSideLength)
    Q_PROPERTY(TrianglePosition m_triPos READ trianglePos WRITE setTrianglePosition)
    Q_PROPERTY(QColor m_triColor READ triangleColor WRITE setTriangleColor)
public:
    explicit JNaviButton(QWidget *parent = 0);

    enum TextAlign {
   
   
        TextAlign_Left = 0x0001,        // 左对齐
        TextAlign_Right = 0x0002,       // 右对齐
        TextAlign_Top = 0x0020,         // 顶部对齐
        TextAlign_Bottom = 0x0040,      // 底部对齐
        TextAlign_Center = 0x0004       // 居中对齐
    };

    enum IconPosition {
   
   
        IP_Left = 0,                    // 左侧
        IP_Top = 1,                     // 顶部
        IP_Right = 2,                   // 右侧
        IP_Bottom = 3                   // 底部
    };

    enum TrianglePosition {
   
   
        TP_Left = 0,                    // 左侧
        TP_Top = 1,                     // 顶部
        TP_Right = 2,                   // 右侧
        TP_Bottom = 3                   // 底部
    };

protected:
    virtual void enterEvent(QEnterEvent *);
    virtual void leaveEvent(QEvent *);
    virtual void paintEvent(QPaintEvent *);

    void drawBackGround(QPainter *painter);
    void drawText(QPainter *painter);
    void drawIcon(QPainter *painter);
    void drawTriangle(QPainter *painter);

private:
    bool m_hover;                       // 鼠标悬停标志

    int m_paddingLeft;                  // 文字左侧间距
    int m_paddingTop;                   // 文字顶部间距
    int m_paddingRight;                 // 文字右侧间距
    int m_paddingBottom;                // 文字底部间距
    TextAlign m_textAlign;              // 文字对齐方式
    QColor m_nTextColor;                // 正常文字颜色
    QColor m_hTextColor;                // 悬停文字颜色
    QColor m_cTextColor;                // 选中文字颜色
    QPen m_textPen;                     // 文字大小、颜色

    QBrush m_nBgBrush;                  // 正常背景画刷
    QBrush m_hBgBrush;                  // 悬停背景画刷
    QBrush m_cBgBrush;                  // 选中背景画刷

    QColor m_nBgColor;                  // 正常背景颜色
    QColor m_hBgColor;                  // 悬停背景颜色
    QColor m_cBgColor;                  // 选中背景颜色

    bool m_showIcon;                    // 显示图标
    int m_iconSpace;                    // 图标边距,左边显示图标是距离左边边距,顶部显示图标表示距离顶部边距,以此类推
    QSize m_iconSize;                   // 图标尺寸
    QPixmap m_nIcon;                    // 正常图标
    QPixmap m_hIcon;                    // 悬停图标
    QPixmap m_cIcon;                    // 选中图标
    IconPosition m_iconPos;             // 图标显示位置

    bool m_showTriangle;                // 是否显示三角
    int m_triSideLength;                // 三角形边长
    TrianglePosition m_triPos;          // 三角形显示位置
    QColor m_triColor;                  // 三角形显示颜色

public:
    int paddingLeft() const;
    int paddingTop() const;
    int paddingRight() const;
    int paddingBottom() const;
    TextAlign textAlign() const;
    QColor normalTextColor() const;
    QColor hoverTextColor() const;
    QColor checkedTextColor() const;
    QPen textPen() const;

    QBrush normalBgBrush() const;
    QBrush hoverBgBrush() const;
    QBrush checkedBgBrush() const;

    QColor normalBgColor() const;
    QColor hoverBgColor() const;
    QColor checkedBgColor() const;

    bool showIcon() const;
    int iconSpace() const;
    QSize iconSize() const;
    QPixmap normalIcon() const;
    QPixmap hoverIcon() const;
    QPixmap checkedIcon() const;
    IconPosition iconPosition() const;

    bool showTriabgle() const;
    int triangleSideLength() const;
    TrianglePosition trianglePos() const;
    QColor triangleColor() const;

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

public Q_SLOTS:
    void setPaddingLeft(int padding);
    void setPaddingTop(int padding);
    void setPaddingRight(int padding);
    void setPaddingBottom(int padding);
    void setTextAlign(TextAlign align);
    void setNormalTextColor(const QColor &c);
    void setHoverTextColor(const QColor &c);
    void setCheckedTextColor(const QColor &c);
    void setTextPen(const QPen &pen);

    void setNormalBgBrush(const QBrush &b);
    void setHoverBgBrush(const QBrush &b);
    void setCheckedBgBrush(const QBrush &b);

    void setNormalBgColor(const QColor &c);
    void setHoverBgColor(const QColor &c);
    void setCheckedBgColor(const QColor &c);

    void setShowIcon(bool
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值