qt----自定义标题栏

有关自定义标题栏,我么们以QQ为例说明

 

上方红色区域为我们要自定义的标题栏区域。我们可以这样想,先通过  this->setWindowFlags(Qt::FramelessWindowHint| windowFlags()); 去掉程序本身的标题栏。然后我们在最上方自己定义一块区域,当作标题栏来使用。这样,不就实现了自定义标题栏了吗?OK,看下面的自定义区域

#ifndef TITLECLASS_H
#define TITLECLASS_H

#include <QWidget>

class QLabel;
class QPushButton;
class TitleClass : public QWidget
{
    Q_OBJECT
public:
    TitleClass(QWidget *parent = 0);
    ~TitleClass();
protected:
    virtual void mousePressEvent(QMouseEvent *event);       //鼠标拖动事件
    virtual void mouseDoubleClickEvent(QMouseEvent *event); //双击标题栏进行界面的最大化/还原
    virtual bool eventFilter(QObject *watched, QEvent *event);

private:
    void initWidget();      //创建全局的控件
    void Connect();
    void updateMaxsize();   //最大化还原

private slots:
    void slotClicked();   //最小化、最大化/还原、关闭

private:
    QLabel *m_pIconLabel;
    QPushButton *m_pMinisizeButton;
    QPushButton *m_pMaximizeButton;
    QPushButton *m_pCloseButton;
};

#endif // TITLECLASS_H
#include <QApplication>
#include <QEvent>
#include <QMouseEvent>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include "TitleClass.h"

#ifdef Q_OS_WIN
#include <qt_windows.h>
#pragma comment(lib, "user32.lib")
#endif
TitleClass::TitleClass(QWidget *parent)
    : QWidget(parent)
{
    initWidget();
}

TitleClass::~TitleClass()
{

}

void TitleClass::mousePressEvent(QMouseEvent *event)
{
#ifdef Q_OS_WIN
    if(ReleaseCapture())
    {
        QWidget *pWind = this->window();
        if(pWind->isTopLevel())
        {
            SendMessage(HWND(pWind->winId()), WM_SYSCOMMAND, SC_MOVE+HTCAPTION, 0);
        }
    }
    event->ignore();
#endif
}

void TitleClass::mouseDoubleClickEvent(QMouseEvent *event)
{
    Q_UNUSED(event)

    emit m_pMaximizeButton->clicked();
}

bool TitleClass::eventFilter(QObject *watched, QEvent *event)
{
    switch(event->type())
    {
        case QEvent::WindowTitleChange:
        {
            QWidget *pWidget = qobject_cast<QWidget*>(watched);
            if(pWidget)
            {
                m_pTitleLabel->setText(pWidget->windowTitle());
                return true;
            }
        }
    case QEvent::WindowIconChange:
    {
        QWidget *pWidget = qobject_cast<QWidget*>(watched);
        if(pWidget)
        {
            QIcon icon = pWidget->windowIcon();
            m_pIconLabel->setPixmap(icon.pixmap(m_pIconLabel->size()));
            return true;
        }
    }
    case QEvent::WindowStateChange:
    case QEvent::Resize:
        updateMaxsize();
        return true;
    }

    return  QWidget::eventFilter(watched, event);
}

void TitleClass::initWidget()
{
    setFixedHeight(30);

    m_pIconLabel = new QLabel(this);    
    m_pMinisizeButton = new QPushButton(this);
    m_pMaximizeButton = new QPushButton(this);
    m_pCloseButton = new QPushButton(this);

    m_pIconLabel->setFixedSize(32, 32);
    m_pIconLabel->setScaledContents(true);  //按比例缩小内容

    m_pTitleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    m_pMinisizeButton->setFixedSize(27, 22);
    m_pMaximizeButton->setFixedSize(27, 22);
    m_pCloseButton->setFixedSize(27, 22);

    m_pTitleLabel->setObjectName(tr("TitleLabel"));
    m_pMinisizeButton->setObjectName(tr("minisizeButton"));
    m_pMaximizeButton->setObjectName(tr("maximisizeButton"));
    m_pCloseButton->setObjectName(tr("closeButton"));

    m_pMinisizeButton->setToolTip(tr("Minisize"));
    m_pMaximizeButton->setToolTip(tr("Maxsize"));
    m_pCloseButton->setToolTip(tr("Close"));

    QHBoxLayout *hLayout = new QHBoxLayout(this);
    hLayout->addWidget(m_pIconLabel);
    hLayout->addSpacing(5);
    hLayout->addWidget(m_pMinisizeButton);
    hLayout->addWidget(m_pMaximizeButton);
    hLayout->addWidget(m_pCloseButton);
    hLayout->setSpacing(0);
    hLayout->setContentsMargins(5, 0, 5, 0);
    setLayout(hLayout);

    Connect();
}

void TitleClass::Connect()
{
    connect(m_pMinisizeButton, SIGNAL(clicked(bool)), this, SLOT(slotClicked()));
    connect(m_pMaximizeButton, SIGNAL(clicked(bool)), this, SLOT(slotClicked()));
    connect(m_pCloseButton, SIGNAL(clicked(bool)), this, SLOT(slotClicked()));
}

void TitleClass::slotClicked()
{
    QPushButton *pButton = qobject_cast<QPushButton*>(sender());
    QWidget *pWindow = this->window();
    if(pWindow->isTopLevel())
    {
        if(pButton == m_pMinisizeButton)
            pWindow->showMinimized();
        else if(pButton == m_pMaximizeButton)
            pWindow->isMaximized() ?
                  pWindow->showNormal() : pWindow->showMaximized();
        else if(pButton == m_pCloseButton)
            pWindow->close();
    }
}

void TitleClass::updateMaxsize()
{
    QWidget *pWindow = this->window();
    if(pWindow->isTopLevel())
    {
        bool bMaximize = pWindow->isMaximized();
        if(bMaximize)
        {
            m_pMaximizeButton->setToolTip(tr("Restore"));
            m_pMaximizeButton->setProperty("maximizeProperty", "restore");
        }
        else
        {
            m_pMaximizeButton->setToolTip(tr("Maxisize"));
            m_pMaximizeButton->setProperty("maximizeProperty", "maximize");
        }
        m_pMaximizeButton->setStyle(QApplication::style());
    }
}

上面的代码,主要实现拖动、最小化、最大化和关闭按钮,以及自定义图标。那么,怎么用呢?看下面:

this->setWindowFlags(Qt::FramelessWindowHint| windowFlags());

    TitleClass *pTitleBar = new TitleClass(this);
    installEventFilter(pTitleBar);

    resize(400, 300);
    setWindowTitle(tr("Custom Window"));
    setWindowIcon(QIcon("game.ico"));

    QPalette pal(palette());
    pal.setColor(QPalette::Background, QColor(250, 250, 250));
    setAutoFillBackground(true);
    setPalette(pal);

    QVBoxLayout *pLayout = new QVBoxLayout();
    pLayout->addWidget(pTitleBar);
    pLayout->addStretch();
    pLayout->setSpacing(0);
    pLayout->setContentsMargins(0, 0, 0, 0);
    setLayout(pLayout);

 

 

在main.cpp中的构造函数中,将上面的代码添加进去即可。

posted @ 2017-10-17 21:38  Qt王二狗  阅读(746)  评论(0)    收藏  举报