Qt自定义标题栏

#ifndef WINDOWHEADER_H
#define WINDOWHEADER_H
 
#include 
#include 
#include 
#include 
#include 
 
#include 
#include 
#include 
 
// 自定义控件,可拖拽标题栏
class WindowHeader : public QWidget
{
    Q_OBJECT
public:
    // 构造函数
    WindowHeader(const char* name, QWidget *parent);
 
    // 设置关闭按钮icon
    void SetCloseImage(const char* path);
    // 设置最小化按钮icon
    void SetMinImage(const char* path);
    // 设置最大化按钮icon
    void SetMaxImage(const char* path);
    // 设置迷你模式按钮icon
    void SetMiniImage(const char* path);
    // 设置软件配置按钮icon
    void SetSettingImage(const char* path);
    // 设置皮肤按钮icon
    void SetSkinImage(const char* path);
    // 设置软件LOGO按钮icon
    void SetAppLogo(const char* path,int w=20,int h=20);
 
    // 获取软件名
    QString GetAppName() { return m_name; }
protected:
    // 重写鼠标事件
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
 
    virtual bool eventFilter(QObject *obj, QEvent *event);
    void paintEvent(QPaintEvent *event);
 
    // 将信号中转,不直接处理信号
signals:
    void ClickedClose();
    void ClickedMin();
    void ClickedMax();
    void ClickedMini();
    void ClickedSetting();
    void ClickedSkin();
 
private:
    // 应用名
    QString m_name;
    int m_height;
 
    // 关闭按钮
    QToolButton* m_toolbtnClose;
    // 最小化按钮
    QToolButton* m_toolbtnMin;
    // 最大化按钮
    QToolButton* m_toolbtnMax;
    // 迷你模式按钮
    QToolButton* m_toolbtnMini;
    // 软件配置按钮
    QToolButton* m_toolbtnSetting;
    // 皮肤设置按钮
    QToolButton* m_toolbtnSkin;
 
    // 呈现应用名称
    QLabel* m_lableAppName;
    // 呈现应用LOGO
    QLabel* m_lableAppLogo;
 
    // 鼠标上次移动开始时相对屏幕的位置
    QPoint m_pointStart;
    // 鼠标是否持续按下
    bool mbKeepPressed;
 
    // 父窗口的指针
    QWidget *m_widgetParent;
 
    // 最大化/还原
    void updateMaximize();
};
 
#endif // WINDOWHEADER_H
 

cpp文件

#include "WindowHeader.h"
#include 
#include 
#include 
#include 
#include 
#include 
 
WindowHeader::WindowHeader(const char* name, QWidget *parent)
    :QWidget(parent),
      m_name(name),
      m_height(48)
 
{
    // 父窗口指针赋值,并设置父窗口为透明的无边框模式,
    //以后所有的控件将在父窗口中布局,包括菜单栏,工具栏,状态栏以及设置个主窗口,
    m_widgetParent = parent;
    m_widgetParent->setAttribute(Qt::WA_TranslucentBackground);
    m_widgetParent->setWindowFlags(Qt::FramelessWindowHint | m_widgetParent->windowFlags());
 
    //监听父窗口事件,主要用于窗口大小变化
    m_widgetParent->installEventFilter(this);
 
    //设置大小属性,横向伸展,竖向固定
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    this->resize(m_widgetParent->width(), m_height);
 
    //绘制圆角需要设置这两个属性。
    this->setAttribute(Qt::WA_TranslucentBackground);//设置窗口背景透明
    this->setWindowFlags(Qt::FramelessWindowHint);   //设置无边框窗口
 
    // 初始化按钮
    m_toolbtnClose = new QToolButton(this);
    m_toolbtnClose->setText("关闭");
    m_toolbtnMin = new QToolButton(this);
    m_toolbtnMin->setText("最小化");
    m_toolbtnMax = new QToolButton(this);
    m_toolbtnMax->setText("最大化");
    m_toolbtnMini = new QToolButton(this);
    m_toolbtnSetting = new QToolButton(this);
    m_toolbtnSkin = new QToolButton(this);
 
    // 初始化标签
    m_lableAppName = new QLabel(this);
    m_lableAppName->setText(m_name);
    m_lableAppLogo = new QLabel(this);
 
    // 初始化布局
    QHBoxLayout* mainLayout = new QHBoxLayout(this);
    mainLayout->setContentsMargins(0,0,0,0);
    mainLayout->setSpacing(2);
 
    // 设置布局
    mainLayout->addWidget(m_lableAppLogo);
    mainLayout->addWidget(m_lableAppName);
    // 设置“弹簧”,将呈现和按钮功能分开
    mainLayout->addStretch();
    mainLayout->addWidget(m_toolbtnSkin);
    mainLayout->addWidget(m_toolbtnSetting);
    mainLayout->addWidget(m_toolbtnMini);
    mainLayout->addWidget(m_toolbtnMin);
    mainLayout->addWidget(m_toolbtnMax);
    mainLayout->addWidget(m_toolbtnClose);
 
    // 将内部按钮信号全部发送出去,内部不做业务逻辑绑定
    connect(m_toolbtnClose,SIGNAL(clicked(bool)),SIGNAL(ClickedClose()));
    connect(m_toolbtnMax,SIGNAL(clicked(bool)),SIGNAL(ClickedMax()));
    connect(m_toolbtnMin,SIGNAL(clicked(bool)),SIGNAL(ClickedMin()));
    connect(m_toolbtnMini,SIGNAL(clicked(bool)),SIGNAL(ClickedMini()));
    connect(m_toolbtnSetting,SIGNAL(clicked(bool)),SIGNAL(ClickedSetting()));
    connect(m_toolbtnSkin,SIGNAL(clicked(bool)),SIGNAL(ClickedSkin()));
}
 
// 设置应用LOGO
void WindowHeader::SetAppLogo(const char *path,int w,int h)
{
    QPixmap newPix = QPixmap(path).scaled(w,h,Qt::KeepAspectRatio);;
    m_lableAppLogo->setPixmap(newPix);
}
 
void WindowHeader::SetSkinImage(const char *path)
{
    QIcon icon(path);
    m_toolbtnSkin->setIcon(icon);
}
 
void WindowHeader::SetSettingImage(const char *path)
{
    QIcon icon(path);
    m_toolbtnSetting->setIcon(icon);
}
 
void WindowHeader::SetMiniImage(const char *path)
{
    QIcon icon(path);
    m_toolbtnMini->setIcon(icon);
}
 
void WindowHeader::SetMaxImage(const char *path)
{
    QIcon icon(path);
    m_toolbtnMax->setIcon(icon);
}
 
void WindowHeader::SetMinImage(const char *path)
{
    QIcon icon(path);
    m_toolbtnMin->setIcon(icon);
}
 
void WindowHeader::SetCloseImage(const char *path)
{
    QIcon icon(path);
    m_toolbtnClose->setIcon(icon);
}
 
// 重写mouseMoveEvent
void WindowHeader::mouseMoveEvent(QMouseEvent *event)
{
    // 持续按住才做对应事件
    if (mbKeepPressed)
    {
        // 将父窗体移动到父窗体之前的位置加上鼠标移动的位置event->globalPos()- m_pointStart
        m_widgetParent->move(m_widgetParent->geometry().topLeft() + event->globalPos()- m_pointStart);
        // 将鼠标在屏幕中的位置替换为新的位置
        m_pointStart = event->globalPos();
    }
}
 
// 重写mousePressEvent
void WindowHeader::mousePressEvent(QMouseEvent *event)
{
    // 鼠标左键按下事件
    if (event->button() == Qt::LeftButton)
    {
        // 记录鼠标状态
        mbKeepPressed = true;
        // 记录鼠标在屏幕中的位置
        m_pointStart = event->globalPos();
    }
}
 
// 重写mouseReleaseEvent
void WindowHeader::mouseReleaseEvent(QMouseEvent *event)
{
    // 鼠标左键释放
    if (event->button() == Qt::LeftButton)
    {
        // 记录鼠标状态
        mbKeepPressed = false;
    }
}
 
void WindowHeader::updateMaximize()
{
    QWidget *pWindow = this->window();
    if (pWindow->isTopLevel())
    {
        bool bMaximize = pWindow->isMaximized();
        if (bMaximize)
        {
            m_toolbtnMax->setToolTip("还原");
            m_toolbtnMax->setText("还原");
//            m_toolbtnMax->setProperty("maximizeProperty", "restore");
        }
        else
        {
//            m_toolbtnMax->setProperty("maximizeProperty", "maximize");
            m_toolbtnMax->setToolTip("最大化");
            m_toolbtnMax->setText("最大化");
        }
    }
}
 
bool WindowHeader::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == m_widgetParent)
    {
        if(event->type() == QEvent::WindowTitleChange)
        {
            m_name = m_widgetParent->windowTitle();
            m_lableAppName->setText(m_name);
            return true;
        }
        else if(event->type() == QEvent::WindowIconChange)
        {
            QIcon icon = m_widgetParent->windowIcon();
            m_lableAppLogo->setPixmap(icon.pixmap(m_lableAppLogo->size()));
            return true;
        }
        else if(event->type() == QEvent::WindowStateChange || event->type() == QEvent::Resize)
        {
            this->resize(m_widgetParent->width(), m_height);
            updateMaximize();
            return true;
        }
    }
 
    return QWidget::eventFilter(obj, event);
}
 
 
void WindowHeader::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);  // 反锯齿;
    painter.setBrush(QBrush(Qt::red));
    painter.setPen(Qt::transparent);
    QRect rect = this->rect();
    painter.drawRoundedRect(rect, 10, 10);//绘制圆角矩形
 
    //覆盖上面绘制圆角矩形的左下角和右下角
    QRect rect2(QPoint(rect.left(), rect.center().y()), rect.bottomRight());
    painter.drawRect(rect2);
 
//    painter.fillRect(this->rect(), QColor(255, 0, 0, 80));  //QColor最后一个参数80代表背景的透明度
 
    QWidget::paintEvent(event);
}
使用:
#ifndef WIDGET_H
#define WIDGET_H
 
#include 
#include "windowheader.h"
#include 
#include 
#include 
 
class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
 
    void setMenuBar(QMenuBar* menuBar);
    void setCentralWidget(QWidget *widget);
 
protected:
    virtual void paintEvent(QPaintEvent *event);
 
private:
    WindowHeader* m_titleBar;
    QMenuBar* m_menuBar;
 
    QWidget* m_centralWidget;
    QVBoxLayout* m_mainLayout;
 
 
signals:
 
public slots:
};
 
#endif // WIDGET_H
#include "widget.h"
#include 
#include 
#include 
 
Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
 
 
    m_titleBar = new WindowHeader(this->windowTitle().toStdString().c_str(), this);
    connect(m_titleBar, SIGNAL(ClickedClose()),
            this, SLOT(close()));
    connect(m_titleBar, SIGNAL(ClickedMin()),
            this, SLOT(showMinimized()));
    connect(m_titleBar, SIGNAL(ClickedMax()),
            this, SLOT(showMaximized()));
 
    this->setWindowTitle("自定义窗口");
    this->setWindowIcon(QIcon(":reboot.ico"));
 
    m_menuBar = new QMenuBar(this);
    QMenu* menu = new QMenu("文件(&F)", this);
    m_menuBar->addMenu(menu);
    menu->addAction("打开");
 
    m_centralWidget = new QWidget(this);
    m_centralWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    m_mainLayout = new QVBoxLayout;
    m_mainLayout->setContentsMargins(2, 0, 2, 0);
//    qDebug() << m_titleBar->height();
    m_mainLayout->addSpacing(m_titleBar->height());
    m_mainLayout->addWidget(m_menuBar);
    m_mainLayout->addWidget(m_centralWidget);
//    m_mainLayout->addStretch();
    this->setLayout(m_mainLayout);
}
 
void Widget::setCentralWidget(QWidget* widget)
{
    if(widget == NULL)
        return;
 
    m_mainLayout->replaceWidget(m_centralWidget, widget);
    delete m_centralWidget;
    m_centralWidget = widget;
    m_centralWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
//    m_centralWidget->show();
}
 
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);  // 反锯齿;
    QPen pen;
    pen.setStyle(Qt::SolidLine);
    pen.setWidth(1);
    pen.setColor(Qt::red);
    painter.setPen(pen);
 
    //从标题栏左下角开始画
    QRect rect = m_titleBar->rect();
    QRect rect2(rect.bottomLeft(), this->rect().bottomRight()/* - QPoint(2, 0)*/);
    painter.drawRect(rect2);
 
    painter.fillRect(rect2, QColor(255, 0, 0, 30));  //QColor最后一个参数80代表背景的透明度
 
    QWidget::paintEvent(event);
}
 
主程序调用:
Widget* w = new Widget;
    w->setWindowTitle("标题栏");
    w->resize(400, 300);
    w->show();
    QWidget* w2 = new QWidget;
    w->setCentralWidget(w2);
    QPushButton* btn = new QPushButton("OK", w2);
    QVBoxLayout* layout = new QVBoxLayout;
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(btn);
    layout->addStretch();
    w2->setLayout(layout);

你可能感兴趣的:(Qt自定义标题栏)