QT 简单实现自定义标题栏

 参考:
https://blog.csdn.net/GoForwardToStep/article/details/53494800
https://blog.csdn.net/liang19890820/article/details/50555298

上面两个链接是我查找到的两种实现自定义标题栏的方法,在实际应用的过程中觉得比较麻烦,而且标题栏效果不太好调整,所以我整理了下面的方法: 

这里用的自定义标题栏就是一个普通的QWidget,实现了图标、最大化、最小化、关闭按钮以及拖动标题栏实现软件移动的功能。然后,取消系统的标题栏,换上自定义的标题栏就OK了,标题栏效果自己任意调整。

MainWindow的布局设置为verticalLayout,依次加入自定义标题栏、菜单栏、主功能界面。

setWindowFlags(Qt::FramelessWindowHint);

TitleBar *pTitleBar = new TitleBar(this);
pTitleBar->setWindowIcon(":/logo/logo.png", QSize(102, 41));

ui->verticalLayout->insertWidget(0, pTitleBar);
ui->verticalLayout->insertWidget(1, ui->menubar); //把菜单栏添加到自定义的标题栏下面

ui->menubar->setStyleSheet("background-color: transparent");


titlebar.h:

#ifndef TITLEBAR_H
#define TITLEBAR_H

#include <QWidget>

class QLabel;
class QPushButton;

class TitleBar : public QWidget
{
    Q_OBJECT

public:
    explicit TitleBar(QWidget *parent); //这里需要传入主窗口的指针,否则将无法实现拖动标题栏移动
    ~TitleBar();

    void setWindowIcon(QString image_path, QSize size);
    void setWindowTitle(QString title);

protected:
    // 双击标题栏进行界面的最大化/还原
    virtual void mouseDoubleClickEvent(QMouseEvent *event);

    // 进行鼠界面的拖动
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);

private slots:

    // 进行最小化、最大化/还原、关闭操作
    void onClicked();

private:

    // 最大化/还原
    void updateMaximize();


private:
    QLabel *m_pIconLabel;
    QLabel *m_pTitleLabel;

    QPushButton *m_pMinimizeButton;
    QPushButton *m_pMaximizeButton;
    QPushButton *m_pCloseButton;

    // 移动窗口的变量;
    QWidget *p;
    bool m_isPressed;
    QPoint m_startMovePos;
};

#endif // TITLEBAR_H


/*******************************/
titlebar.cpp:

#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QEvent>
#include <QMouseEvent>
#include <QApplication>
#include "titlebar.h"

TitleBar::TitleBar(QWidget *parent)
    : QWidget(parent)
{
    p = parent;

    setFixedHeight(45);

    m_pIconLabel = new QLabel(this);
    m_pTitleLabel = new QLabel(this);
    m_pMinimizeButton = new QPushButton(this);
    m_pMaximizeButton = new QPushButton(this);
    m_pCloseButton = new QPushButton(this);

    m_pIconLabel->setFixedSize(20, 20);
    m_pIconLabel->setScaledContents(true);

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

    m_pMinimizeButton->setFixedSize(36, 36);
    m_pMaximizeButton->setFixedSize(36, 36);
    m_pCloseButton->setFixedSize(36, 36);

    m_pMinimizeButton->setIconSize(QSize(30, 30));
    m_pMinimizeButton->setStyleSheet("border-style: flat;");
    m_pMaximizeButton->setIconSize(QSize(30, 30));
    m_pMaximizeButton->setStyleSheet("border-style: flat;");
    m_pCloseButton->setIconSize(QSize(30, 30));
    m_pCloseButton->setStyleSheet("border-style: flat;");

    m_pMinimizeButton->setIcon(QIcon(":/logo/min.ico"));
    m_pMaximizeButton->setIcon(QIcon(":/logo/max.ico"));
    m_pCloseButton->setIcon(QIcon(":/logo/close.ico"));

    m_pTitleLabel->setObjectName("whiteLabel");
    m_pMinimizeButton->setObjectName("minimizeButton");
    m_pMaximizeButton->setObjectName("maximizeButton");
    m_pCloseButton->setObjectName("closeButton");

    m_pMinimizeButton->setToolTip("Minimize");
    m_pMaximizeButton->setToolTip("Maximize");
    m_pCloseButton->setToolTip("Close");

    QHBoxLayout *pLayout = new QHBoxLayout(this);
    pLayout->addWidget(m_pIconLabel);
    pLayout->addSpacing(5);
    pLayout->addWidget(m_pTitleLabel);
    pLayout->addWidget(m_pMinimizeButton);
    pLayout->addWidget(m_pMaximizeButton);
    pLayout->addWidget(m_pCloseButton);
    pLayout->setSpacing(0);
    pLayout->setContentsMargins(5, 0, 5, 0);

    setLayout(pLayout);

    connect(m_pMinimizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));
    connect(m_pMaximizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));
    connect(m_pCloseButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));
}

TitleBar::~TitleBar()
{

}

void TitleBar::setWindowIcon(QString image_path, QSize size)
{
    m_pIconLabel->setFixedSize(size);
    m_pIconLabel->setPixmap(QPixmap(image_path));
}

void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
    Q_UNUSED(event);

    emit m_pMaximizeButton->clicked();

    event->accept();
}

void TitleBar::mousePressEvent(QMouseEvent *event)
{
    Q_UNUSED(event);

    m_isPressed = true;
    m_startMovePos = event->globalPos();

    event->accept();
}

void TitleBar::mouseMoveEvent(QMouseEvent *event)
{
    if (m_isPressed)
    {
        QPoint movePoint = event->globalPos() - m_startMovePos;
        QPoint widgetPos = p->pos();
        m_startMovePos = event->globalPos();

        p->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());

        //this->parentWidget()->pos();
        //this->parentWidget()->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());
     }

    event->accept();
}

void TitleBar::mouseReleaseEvent(QMouseEvent *event)
{
    m_isPressed = false;

    event->accept();
}

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

void TitleBar::updateMaximize()
{
    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->setProperty("maximizeProperty", "maximize");
            m_pMaximizeButton->setToolTip(tr("Maximize"));
        }

        m_pMaximizeButton->setStyle(QApplication::style());
    }
}



 

在Linux下,可以通过自定义QWidget来实现自定义标题栏。具体实现步骤如下: 1. 创建一个继承自QWidget的类,用于实现自定义标题栏。 ```cpp class MyTitleBar : public QWidget { Q_OBJECT public: explicit MyTitleBar(QWidget *parent = nullptr); protected: void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; private: QPoint m_lastPos; }; ``` 2. 在构造函数中设置标题栏的大小、背景色和布局。 ```cpp MyTitleBar::MyTitleBar(QWidget *parent) : QWidget(parent) { setFixedHeight(30); setStyleSheet("background-color: #333333"); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); setLayout(layout); } ``` 3. 重写mousePressEvent和mouseMoveEvent函数,实现标题栏的拖动。 ```cpp void MyTitleBar::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_lastPos = event->globalPos() - this->parentWidget()->geometry().topLeft(); } } void MyTitleBar::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { QPoint pos = event->globalPos() - m_lastPos; this->parentWidget()->move(pos); } } ``` 4. 在主窗口中添加自定义标题栏,并将系统标题栏隐藏。 ```cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setWindowTitle("Custom Title Bar"); setWindowFlags(Qt::FramelessWindowHint | windowFlags()); MyTitleBar *titleBar = new MyTitleBar(this); setMenuWidget(titleBar); // 添加其他控件及布局 // ... } ``` 5. 编译运行程序,即可看到自定义标题栏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值