Qt自定义标题栏用法
原文:https://blog.****.net/naibozhuan3744/article/details/81120544
本博客主要总结创建Qt工程时,不用系统自带的标题栏,而是用自定义的标题栏。其中,自定义标题栏主要原理是,屏蔽原来的标题栏,然后用QVBoxLayout垂直布局管理器,加载一个标题栏QWidget。其中,这个标题栏QWidget里面自定义标题栏的功能按钮,比如图标、图标内容、最大化按钮(QWidget::showMaximized())、最小化按钮(QWidget::showMinimized())、关闭按钮(QWidget::close())。
下面的一个实例是自定义的一个标题栏。这个实例的主要代码是参考这篇博客里面的,我只是对其中进行了修改和封装了一层QWidget。自定义标题的功能主要封装在类title_bar里面,只需要调用该类title_bar,然后用一个垂直布局将其关联起来,就可以实现自定义标题栏。
主要参考代码博客地址:https://blog.****.net/liang19890820/article/details/50555298(作者:一去丶二三里)
注意,屏蔽主界面标题栏,只需要用下面这条语句就行:
setWindowFlags(Qt::FramelessWindowHint | windowFlags());
1.1新建一个widget工程,不要勾选ui界面。然后添加一个类,类名为title_bar,基类为QWidget。
然后分别在title_bar.h,title_bar.cpp,widget.h,widget.cpp,main.cpp分别添加如下代码。
title_bar.h
#ifndef TITLE_BAR
#define TITLE_BAR
#include <QWidget>
class QLabel;
class QPushButton;
class TitleBar : public QWidget
{
Q_OBJECT
public:
explicit TitleBar(QWidget *parent = 0);
~TitleBar();
protected:
// 双击标题栏进行界面的最大化/还原
virtual void mouseDoubleClickEvent(QMouseEvent *event);
// 进行鼠界面的拖动
virtual void mousePressEvent(QMouseEvent *event);
// 设置界面标题与图标
virtual bool eventFilter(QObject *obj, QEvent *event);
private slots:
// 进行最小化、最大化/还原、关闭操作
void onClicked();
private:
// 最大化/还原
void updateMaximize();
private:
QLabel *m_pIconLabel;
QLabel *m_pTitleLabel;
QPushButton *m_pMinimizeButton;
QPushButton *m_pMaximizeButton;
QPushButton *m_pCloseButton;
};
#endif // TITLE_BAR
title_bar.cpp
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QEvent>
#include <QMouseEvent>
#include <QApplication>
#include "title_bar.h"
#ifdef Q_OS_WIN
#include <qt_windows.h>
#endif
TitleBar::TitleBar(QWidget *parent)
: QWidget(parent)
{
setFixedHeight(30);
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(30, 30);
m_pMaximizeButton->setFixedSize(30, 30);
m_pCloseButton->setFixedSize(30, 30);
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");
m_pTitleLabel->setContentsMargins(8,0,0,0);
m_pTitleLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_pMinimizeButton->setIcon(QIcon(":/icon/minus.png"));
m_pMaximizeButton->setIcon(QIcon(":/icon/maximize.png"));
m_pCloseButton->setIcon(QIcon(":/icon/close.png"));
QHBoxLayout *mainWidgetLayout = new QHBoxLayout(this);
QWidget *mainWidget = new QWidget;
QHBoxLayout *pLayout = new QHBoxLayout;
mainWidgetLayout->addWidget(mainWidget);
mainWidget->setLayout(pLayout);
mainWidgetLayout->setMargin(0);
pLayout->setContentsMargins(7,0,0,0);
pLayout->setSpacing(0);
mainWidget->setStyleSheet("QWidget{background-color:rgb(150,150,150);}");
pLayout->addWidget(m_pIconLabel);
pLayout->addWidget(m_pTitleLabel);
pLayout->addStretch();
pLayout->addWidget(m_pMinimizeButton);
pLayout->addWidget(m_pMaximizeButton);
pLayout->addWidget(m_pCloseButton);
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::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_UNUSED(event);
emit m_pMaximizeButton->clicked();
}
void TitleBar::mousePressEvent(QMouseEvent *event)
{
#ifdef Q_OS_WIN
if (ReleaseCapture())
{
QWidget *pWindow = this->window();
if (pWindow->isTopLevel())
{
SendMessage(HWND(pWindow->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}
}
event->ignore();
#else
#endif
}
bool TitleBar::eventFilter(QObject *obj, QEvent *event)
{
switch (event->type())
{
case QEvent::WindowTitleChange:
{
QWidget *pWidget = qobject_cast<QWidget *>(obj);
if (pWidget)
{
m_pTitleLabel->setText(pWidget->windowTitle());
return true;
}
}
case QEvent::WindowIconChange:
{
QWidget *pWidget = qobject_cast<QWidget *>(obj);
if (pWidget)
{
QIcon icon = pWidget->windowIcon();
m_pIconLabel->setPixmap(icon.pixmap(m_pIconLabel->size()));
return true;
}
}
case QEvent::WindowStateChange:
case QEvent::Resize:
updateMaximize();
return true;
default:
return QWidget::eventFilter(obj, event);
}
return QWidget::eventFilter(obj, event);
}
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());
}
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
};
#endif // WIDGET_H
widget.cpp
#include <QVBoxLayout>
#include <QPixmap>
#include <QIcon>
#include <QTableWidget>
#include <QPushButton>
#include "widget.h"
#include "title_bar.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
setWindowFlags(Qt::FramelessWindowHint | windowFlags());
TitleBar *pTitleBar = new TitleBar(this);
installEventFilter(pTitleBar);
resize(960, 640);
setWindowTitle("Custom Window");
setWindowIcon(QIcon(":/icon/24x24.ico"));
QPalette pal(palette());
pal.setColor(QPalette::Background, QColor(0, 0, 0));
setAutoFillBackground(true);
setPalette(pal);
QTableWidget *tableListWidget = new QTableWidget;
QPushButton *pushButton = new QPushButton("button");
pushButton->setStyleSheet("QPushButton{background-color:rgb(115,115,115);color:white}");
QVBoxLayout *pLayout = new QVBoxLayout();
pLayout->addWidget(pTitleBar);
pLayout->addWidget(pushButton);
pLayout->addWidget(tableListWidget);
pLayout->setSpacing(0);
pLayout->setMargin(0);
setLayout(pLayout);
}
Widget::~Widget()
{
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
1.2程序构建运行后,结果如下图所示: