自定义 TitleBar

#ifndef TITLEBAR_H
#define TITLEBAR_H

#include <QWidget>
#include <QtCore>
#include <QtGui>


class TitleBar : public QWidget
{
    Q_OBJECT

public:

    const static int VALUE_DIS = 1;
    const static int TITLE_H = 22;

    //枚举,按钮状态
    enum eBtnMoustState{
         eBtnStateNone,//无效
         eBtnStateDefault,//默认值(如按钮初始显示)
         eBtnStateHover,//鼠标移到按钮上状态
         eBtnStatePress//鼠标按下按钮时状态
     };

    QLabel *m_pLabelLogo;
    QLabel *m_pLabelTitle;

    QToolButton *m_pBtnSkin;
    QToolButton *m_pBtnMenu;
    QToolButton *m_pBtnMin;
    QToolButton *m_pBtnMax;
    QToolButton *m_pBtnClose;

   QHBoxLayout *m_pLayout;

   bool m_bLeftButtonPress;

   QPoint m_ptPress;
   QPoint m_ptMove;

   QWidget *m_parent;

   QFrame *m_bkFrame;

   int m_windowState;

public:
    explicit TitleBar(QWidget *parent = 0);
    ~TitleBar();

    //创建子部件
    void createWidget();

    //设置子部件样式(qss)
    void setWidgetStyle();

    void setBtnIcon(QToolButton *pBtn, eBtnMoustState state);

    //创建设置布局
    void createLayout();

    //获得图片路径(固定值)
    const QString getBtnImagePath(QToolButton *pBtn);

    //创建事件过滤器
    void createEventFiter();

    //事件过滤
    bool eventFilter(QObject *obj, QEvent *event);

    //鼠标按下事件
    void mousePressEvent(QMouseEvent *event);
    //鼠标移动事件
    void mouseMoveEvent(QMouseEvent *event);
    //鼠标释放事件
    void mouseReleaseEvent(QMouseEvent *event);
    //鼠标双击事件
    void mouseDoubleClickEvent(QMouseEvent * );

signals:
    void signal_showMinimized();
    void signal_showMaximizedNormal();
    void signal_close();
    void signal_move(const QPoint &pos);
    void signal_popupMenu(const QPoint &pos);

public slots:
    //槽函数--slot_btnclick
    void slot_btnclick();

private:
};

#endif // TITLEBAR_H

.cpp

#include "titlebar.h"


TitleBar::TitleBar(QWidget *parent) :
    QWidget(parent)
{
    m_windowState = Qt::WindowNoState;
    m_bLeftButtonPress = false;
    createWidget();
    createLayout();
    createEventFiter();
    setWidgetStyle();
}

TitleBar::~TitleBar()
{
}

//创建子部件
void TitleBar::createWidget()
{
    m_bkFrame = new QFrame(this);
    //图像标签--logo
    m_pLabelLogo = new QLabel(this);
    QPixmap objPixmap(":Resources/images/logo.png");
    m_pLabelLogo->setPixmap(objPixmap.scaled(TITLE_H, TITLE_H, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
    //文本标签--标题
    m_pLabelTitle = new QLabel(this);
    //按钮--更换皮肤
    m_pBtnSkin = new QToolButton(this);
    //设置初始图片
    setBtnIcon(m_pBtnSkin,eBtnStateDefault);
    //按钮--菜单
    m_pBtnMenu = new QToolButton(this);
    m_pBtnMenu->setToolTip(QString("主菜单"));
    setBtnIcon(m_pBtnMenu,eBtnStateDefault);
    //按钮--最小化
    m_pBtnMin = new QToolButton(this);
    m_pBtnMin->setToolTip(QString("最小化"));
    setBtnIcon(m_pBtnMin,eBtnStateDefault);
    //按钮--最大化/还原
    m_pBtnMax = new QToolButton(this);
    m_pBtnMax->setToolTip(QString("最大化"));
    setBtnIcon(m_pBtnMax,eBtnStateDefault);
    //按钮--关闭
    m_pBtnClose = new QToolButton(this);
    m_pBtnClose->setToolTip(QString("关闭"));
    setBtnIcon(m_pBtnClose,eBtnStateDefault);
    //获得子部件
    const QObjectList &objList = children();
    for(int nIndex=0; nIndex<objList.count();++nIndex)
    {
        //设置子部件的MouseTracking属性
        ((QWidget*)(objList.at(nIndex)))->setMouseTracking(true);
        //如果是QToolButton部件
        if (0==qstrcmp(objList.at(nIndex)->metaObject()->className(),"QToolButton"))
        {
            //连接clicked信号为slot_btnclick
            connect(((QToolButton*)(objList.at(nIndex))),SIGNAL(clicked()),this,SLOT(slot_btnclick()));
            //设置顶部间距
            ((QToolButton*)(objList.at(nIndex)))->setContentsMargins(0,VALUE_DIS,0,0);
        }
    }
}

//设置子部件样式(qss)
void TitleBar::setWidgetStyle()
{
    
   // m_bkFrame->setStyleSheet("QFrame{border-top-left-radius: 5px;border-top-right-radius: 5px;background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 rgba(206,146,146,100),stop:0.49 rgba(110, 80, 77, 100),stop:0.51 rgba(69, 17, 14, 100),stop:0.92 rgba(176, 62, 60, 50),stop:1 rgba(238, 90, 90, 30));}");
    m_pLabelTitle->setStyleSheet("QLabel{margin-left:6px;background-color: transparent;color:#ffffff;font-size:12px;font-weight:bold;}");
    m_pLabelLogo->setStyleSheet("QLabel{background-color: transparent;color:#ffffff;font-size:12px;font-weight:bold;}");
    //设置标签的文本颜色,大小等以及按钮的边框
    setStyleSheet("\
                  QToolButton{border:0px;}\
                  QToolButton::menu-button {image: url(none);}");
    //设置左边距
//    m_pLabelTitle->setStyleSheet("margin-left:6px;");
}

//创建设置布局
void TitleBar::createLayout()
{
    QGridLayout *gl = new QGridLayout(this);
    gl->setContentsMargins(0, 0, 0, 0);
    gl->setSpacing(0);
    setLayout(gl);
    gl->addWidget(m_bkFrame);
    //水平布局
    m_pLayout = new QHBoxLayout(m_bkFrame);
    //添加部件
    m_pLayout->addWidget(m_pLabelLogo);
    m_pLayout->addWidget(m_pLabelTitle);
    //添加伸缩项
    m_pLayout->addStretch(1);
    //添加部件
//    m_pLayout->addWidget(m_pLabelVersion);
    m_pLayout->addWidget(m_pBtnSkin);
    m_pLayout->addWidget(m_pBtnMenu);
    m_pLayout->addWidget(m_pBtnMin);
    m_pLayout->addWidget(m_pBtnMax);
    m_pLayout->addWidget(m_pBtnClose);
    //设置Margin
    m_pLayout->setContentsMargins(5,0,VALUE_DIS,0);
    //设置部件之间的space
    m_pLayout->setSpacing(0);
    m_bkFrame->setLayout(m_pLayout);
}

//设置按钮不同状态下的图标
void TitleBar::setBtnIcon(QToolButton *pBtn,eBtnMoustState state)
{
    //获得图片路径
    QString strImagePath = getBtnImagePath(pBtn);
    //创建QPixmap对象
    QPixmap objPixmap(strImagePath);
    //得到图像宽和高
    int nPixWidth = objPixmap.width();
    int nPixHeight = objPixmap.height();
    //如果状态不是无效值
    if (state!=eBtnStateNone)
    {
        /*设置按钮图片
        按钮的图片是连续在一起的,如前1/4部分表示默认状态下的图片部分,接后的1/4部分表示鼠标移到按钮状态下的图片部分
        */
        pBtn->setIcon(objPixmap.copy((nPixWidth/4)*(state-1),0,nPixWidth/4,nPixHeight));
        //设置按钮图片大小
        pBtn->setIconSize(QSize(nPixWidth/4,nPixHeight));
    }
}


//获得图片路径(固定值)
const QString TitleBar::getBtnImagePath(QToolButton *pBtn)
{
    QString strImagePath;
    //皮肤按钮
    if (m_pBtnSkin==pBtn)
    {
        strImagePath = ":Resources/images/SkinButtom.png";
    }
    //菜单按钮
    if (m_pBtnMenu==pBtn)
    {
        strImagePath = ":Resources/images/title_bar_menu.png";
    }
    //最小化
    if (m_pBtnMin==pBtn)
    {
        strImagePath = ":Resources/images/sys_button_min.png";
    }
    //最大化/还原按钮,所以包括最大化和还原两张图片
    if (m_pBtnMax==pBtn)
    {
        //如果是初始设置或者主界面的最大化标志不为真(其中MainWindow::Instance()使用单例设计模式)
//        if (bInit==true || MainWindowNLTP::instance()->getMaxWin()==false)
        if (Qt::WindowMaximized == m_windowState)
        {
            //还原按钮图片路径
            strImagePath = ":Resources/images/sys_button_restore.png";
            m_pBtnMax->setToolTip(QString("还原"));
        }
        else
        {
            //最大化按钮图片路径
            strImagePath = ":Resources/images/sys_button_max.png";
            m_pBtnMax->setToolTip(QString("最大化"));
         }
    }
    //关闭按钮
    if (m_pBtnClose==pBtn)
    {
        strImagePath = ":Resources/images/sys_button_close.png";
    }
    return strImagePath;
}


//创建事件过滤器
void TitleBar::createEventFiter()
{
    m_pBtnSkin->installEventFilter(this);
    m_pBtnMenu->installEventFilter(this);
    m_pBtnMin->installEventFilter(this);
    m_pBtnMax->installEventFilter(this);
    m_pBtnClose->installEventFilter(this);
}

//事件过滤
bool TitleBar::eventFilter(QObject *obj, QEvent *event)
{
    //按钮状态
    eBtnMoustState eState = eBtnStateNone;
    //判断事件类型--QEvent::Enter
    if (event->type() == QEvent::Enter)
    {
        eState = eBtnStateHover;
    }
    //判断事件类型--QEvent::Leave
    if (event->type() == QEvent::Leave)
    {
        eState = eBtnStateDefault;
    }
    //判断事件类型--QEvent::MouseButtonPress
    if (event->type() == QEvent::MouseButtonPress && ((QMouseEvent*)(event))->button()== Qt::LeftButton)
    {
        eState = eBtnStatePress;
    }
    //判断目标
    if (m_pBtnSkin==obj || m_pBtnMenu==obj || m_pBtnMin==obj || m_pBtnMax==obj || m_pBtnClose==obj)
    {
        //如果状态有效
        if (eState != eBtnStateNone)
        {
            //根据状态设置按钮图标
            setBtnIcon((QToolButton *)obj,eState);
            return false;
        }
    }
    return QWidget::eventFilter(obj,event);
}

//槽函数--slot_btnclick
void TitleBar::slot_btnclick()
{
    QToolButton *pBtn = (QToolButton*)(sender());
    if (pBtn==m_pBtnMin)
    {
        emit signal_showMinimized();
    }
    else if (pBtn==m_pBtnMax)
    {
        emit signal_showMaximizedNormal();
    }
    else if (pBtn==m_pBtnClose)
    {
        emit signal_close();
    }
    else if (pBtn==m_pBtnMenu)
    {
        QPoint pos = mapToGlobal(QPoint(m_pBtnMenu->x(), m_pBtnMenu->y() + m_pBtnMenu->height()));
        emit signal_popupMenu(pos);
    }
}

//鼠标双击事件
void TitleBar::mouseDoubleClickEvent(QMouseEvent *)
{
    emit signal_showMaximizedNormal();
    setBtnIcon(m_pBtnMax, eBtnStateDefault);
}

//鼠标按下事件
void TitleBar::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        if (event->y() < VALUE_DIS
        || event->x() < VALUE_DIS
        || rect().width() - event->x() < 5)
        {
            event->ignore();
            return;
        }
        m_ptPress = event->globalPos();
        m_bLeftButtonPress = true;
    }
    event->ignore();
}

//鼠标移动事件
void TitleBar::mouseMoveEvent(QMouseEvent *event)
{
    if (m_bLeftButtonPress)
    {
        m_ptMove = event->globalPos();
        //移动主窗口
        emit signal_move(m_ptMove-m_ptPress);
        //重新设置m_ptPress;
        m_ptPress = m_ptMove;
    }
    event->ignore();
}

//鼠标释放事件
void TitleBar::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        m_bLeftButtonPress = false;
    }
     event->ignore();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值