Qt添加自定義標題欄
在原文基礎上稍加改動,使之更適用於項目
新建mytitle類,定義代碼如下
mytitle.h
#ifndef _MyTitleBar_H_
#define _MyTitleBar_H_
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QTimer>
#include <QDesktopWidget>
#include <QApplication>
//設置標題字體樣式
struct struTitleStyle
{
int title_height = 60; // 標題欄高度;
int btn_height = 30; // 按鈕高度;
int btn_width = 30; // 按鈕寬度;
QString family = "Microsoft YaHei"; // 字體
int FontSize = 18; // 字體大小(單位:px)
QColor color = qRgb(0, 0, 0); // 字體顏色
bool Bold = false; // 字體加粗
};
class MyTitleBar : public QWidget
{
Q_OBJECT
public:
MyTitleBar(QWidget *parent);
// 這里parent沒有給默認值NULL,保證在創建MyTitleBar對象時父指針必須得賦值;且賦值不為NULL;
~MyTitleBar();
// 設置標題欄樣式
void setTitleStyle(struTitleStyle &struTitleStyle);
// 設置標題欄背景色及是否設置標題欄背景色透明;
void setBackgroundColor(int r, int g, int b , bool isTransparent = false);
// 設置標題欄圖標,默認圖標大小為30px×30px
void setTitleIcon(QString filePath , QSize IconSize = QSize(30 , 30));
// 設置標題字體樣式
void setFontStyle();
// 設置標題內容
void setTitleContent(QString titleContent="Title" );
// 設置標題欄長度;
void setTitleWidth(int width);
// 設置窗口邊框寬度;
void setWindowBorderWidth(int borderWidth = 0);
// 設置只有關閉按鈕可見
bool setCloseButton();
// 設置是否啟用雙擊最大化功能,默認false
void setMouseDoubleClick(bool b = false);
// 保存/獲取 最大化前窗口的位置及大小;
void saveRestoreInfo(const QPoint point, const QSize size);
void getRestoreInfo(QPoint& point, QSize& size);
private:
void paintEvent(QPaintEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
// 初始化控件;
void initControl();
// 信號槽的綁定;
void initConnections();
private slots:
// 按鈕觸發的槽;
void onButtonMinClicked();
void onButtonRestoreClicked();
void onButtonMaxClicked();
void onButtonCloseClicked();
private:
struTitleStyle m_struTitleStyle; // 標題欄樣式
QLabel *m_pIcon; // 標題欄圖標;
QLabel *m_pTitleContent; // 標題欄內容;
QPushButton *m_pButtonMin; // 最小化按鈕;
QPushButton *m_pButtonRestore; // 最大化還原按鈕;
QPushButton *m_pButtonMax; // 最大化按鈕;
QPushButton *m_pButtonClose; // 關閉按鈕;
// 標題欄背景色;
int m_colorR;
int m_colorG;
int m_colorB;
// 最大化,最小化變量;
QPoint m_restorePos;
QSize m_restoreSize;
// 移動窗口的變量;
bool m_isPressed;
QPoint m_startMovePos;
// 標題欄內容;
QString m_titleContent;
// 窗口邊框寬度;
int m_windowBorderWidth;
// 標題欄是否透明;
bool m_isTransparent;
// 是否啟用雙擊最大化
bool m_mouseDoubleClickEvent;
};
#endif
mytitle.cpp
#include "mytitlebar.h"
#include <QHBoxLayout>
#include <QPainter>
#include <QFile>
#include <QMouseEvent>
MyTitleBar::MyTitleBar(QWidget *parent)
: QWidget(parent)
, m_colorR(192)
, m_colorG(192)
, m_colorB(192)
, m_isPressed(false)
, m_windowBorderWidth(0)
, m_isTransparent(true)
{
// 初始化;
initControl();
initConnections();
m_pButtonRestore->setVisible(false);
}
MyTitleBar::~MyTitleBar()
{
}
/***********************************************************************
Function: // setTitleStyle
Description: // 設置標題欄樣式
Return: // void
************************************************************************/
void MyTitleBar::setTitleStyle(struTitleStyle &struTitleStyle)
{
m_struTitleStyle = struTitleStyle;
}
// 初始化控件;
void MyTitleBar::initControl()
{
m_pIcon = new QLabel;
m_pTitleContent = new QLabel;
m_pButtonMin = new QPushButton;
m_pButtonRestore = new QPushButton;
m_pButtonMax = new QPushButton;
m_pButtonClose = new QPushButton;
m_pButtonMin->setFixedSize(QSize(m_struTitleStyle.btn_width, m_struTitleStyle.btn_height));
m_pButtonRestore->setFixedSize(QSize(m_struTitleStyle.btn_width, m_struTitleStyle.btn_height));
m_pButtonMax->setFixedSize(QSize(m_struTitleStyle.btn_width, m_struTitleStyle.btn_height));
m_pButtonClose->setFixedSize(QSize(m_struTitleStyle.btn_width, m_struTitleStyle.btn_height));
m_pTitleContent->setObjectName("TitleName");
m_pButtonMin->setObjectName("ButtonMin");
m_pButtonRestore->setObjectName("ButtonRestore");
m_pButtonMax->setObjectName("ButtonMax");
m_pButtonClose->setObjectName("ButtonClose");
m_pButtonMin->setToolTip("最小化");
m_pButtonRestore->setToolTip("還原");
m_pButtonMax->setToolTip("最大化");
m_pButtonClose->setToolTip("關閉");
QHBoxLayout* mylayout = new QHBoxLayout(this);
mylayout->addWidget(m_pIcon);
mylayout->addWidget(m_pTitleContent);
mylayout->addWidget(m_pButtonMin);
mylayout->addWidget(m_pButtonRestore);
mylayout->addWidget(m_pButtonMax);
mylayout->addWidget(m_pButtonClose);
mylayout->setContentsMargins(5, 0, 0, 0);
mylayout->setSpacing(0);
m_pTitleContent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
this->setFixedHeight(m_struTitleStyle.title_height);
this->setWindowFlags(Qt::FramelessWindowHint);
}
// 信號槽的綁定;
void MyTitleBar::initConnections()
{
connect(m_pButtonMin, SIGNAL(clicked()), this, SLOT(onButtonMinClicked()));
connect(m_pButtonRestore, SIGNAL(clicked()), this, SLOT(onButtonRestoreClicked()));
connect(m_pButtonMax, SIGNAL(clicked()), this, SLOT(onButtonMaxClicked()));
connect(m_pButtonClose, SIGNAL(clicked()), this, SLOT(onButtonCloseClicked()));
}
// 設置標題欄背景色,在paintEvent事件中進行繪制標題欄背景色;
// 在構造函數中給了默認值,可以外部設置顏色值改變標題欄背景色;
void MyTitleBar::setBackgroundColor(int r, int g, int b, bool isTransparent)
{
m_colorR = r;
m_colorG = g;
m_colorB = b;
m_isTransparent = isTransparent;
// 重新繪制(調用paintEvent事件);
update();
}
// 設置標題欄圖標;
void MyTitleBar::setTitleIcon(QString filePath, QSize IconSize)
{
QPixmap titleIcon(filePath);
m_pIcon->setPixmap(titleIcon.scaled(IconSize));
}
/***********************************************************************
Function: // setFontStyle
Description: // 設置標題欄字體樣式
Return: // void
************************************************************************/
void MyTitleBar::setFontStyle()
{
// 設置標題字體大小;
QFont font = m_pTitleContent->font();
font.setFamily(m_struTitleStyle.family);
font.setPixelSize(m_struTitleStyle.FontSize);
font.setBold(m_struTitleStyle.Bold);
QPalette l_palette;
l_palette.setColor(QPalette::WindowText, m_struTitleStyle.color);
m_pTitleContent->setPalette(l_palette);
m_pTitleContent->setFont(font);
}
// 設置標題內容;
void MyTitleBar::setTitleContent(QString titleContent)
{
m_pTitleContent->setText(titleContent);
m_titleContent = titleContent;
setFontStyle();
}
// 設置標題欄長度;
void MyTitleBar::setTitleWidth(int width)
{
this->setFixedWidth(width);
}
// 設置窗口邊框寬度;
void MyTitleBar::setWindowBorderWidth(int borderWidth)
{
m_windowBorderWidth = borderWidth;
}
/***********************************************************************
Function: // setCloseButton
Description: // 設置只有關閉按鈕可見
Return: // bool
************************************************************************/
bool MyTitleBar::setCloseButton()
{
m_pButtonMin->setVisible(false);
m_pButtonRestore->setVisible(false);
m_pButtonMax->setVisible(false);
return true;
}
/***********************************************************************
Function: // setMouseDoubleClick
Description: // 設置是否啟用雙擊最大化
Return: // bool
************************************************************************/
void MyTitleBar::setMouseDoubleClick(bool b)
{
m_mouseDoubleClickEvent = b;
}
// 保存窗口最大化前窗口的位置以及大小;
void MyTitleBar::saveRestoreInfo(const QPoint point, const QSize size)
{
m_restorePos = point;
m_restoreSize = size;
}
// 獲取窗口最大化前窗口的位置以及大小;
void MyTitleBar::getRestoreInfo(QPoint& point, QSize& size)
{
point = m_restorePos;
size = m_restoreSize;
}
// 繪制標題欄背景色;
void MyTitleBar::paintEvent(QPaintEvent *event)
{
// 是否設置標題透明;
if (!m_isTransparent)
{
//設置背景色;
QPainter painter(this);
QPainterPath pathBack;
pathBack.setFillRule(Qt::WindingFill);
pathBack.addRoundedRect(QRect(0, 0, this->width(), this->height()), 3, 3);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.fillPath(pathBack, QBrush(QColor(m_colorR, m_colorG, m_colorB)));
}
// 當窗口最大化或者還原后,窗口長度變了,標題欄的長度應當一起改變;
// 這里減去m_windowBorderWidth ,是因為窗口可能設置了不同寬度的邊框;
// 如果窗口有邊框則需要設置m_windowBorderWidth的值,否則m_windowBorderWidth默認為0;
if (this->width() != (this->parentWidget()->width() - m_windowBorderWidth))
{
this->setFixedWidth(this->parentWidget()->width() - m_windowBorderWidth);
}
QWidget::paintEvent(event);
}
// 雙擊響應事件,主要是實現雙擊標題欄進行最大化和最小化操作;
void MyTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
// 判斷是否啟用雙擊最大化功能,默認false
if(m_mouseDoubleClickEvent == false)
{
return;
}
// 通過最大化按鈕的狀態判斷當前窗口是處於最大化還是原始大小狀態;
// 或者通過單獨設置變量來表示當前窗口狀態;
if (m_pButtonMax->isVisible())
{
onButtonMaxClicked();
}
else
{
onButtonRestoreClicked();
}
return QWidget::mouseDoubleClickEvent(event);
}
// 以下通過mousePressEvent、mouseMoveEvent、mouseReleaseEvent三個事件實現了鼠標拖動標題欄移動窗口的效果;
void MyTitleBar::mousePressEvent(QMouseEvent *event)
{
// 在窗口最大化時禁止拖動窗口;
if (m_pButtonMax->isVisible())
{
m_isPressed = true;
m_startMovePos = event->globalPos();
}
else
{
m_isPressed = true;
m_startMovePos = event->globalPos();
}
return QWidget::mousePressEvent(event);
}
void MyTitleBar::mouseMoveEvent(QMouseEvent *event)
{
if (m_isPressed)
{
QPoint movePoint = event->globalPos() - m_startMovePos;
QPoint widgetPos = this->parentWidget()->pos();
m_startMovePos = event->globalPos();
this->parentWidget()->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());
}
return QWidget::mouseMoveEvent(event);
}
void MyTitleBar::mouseReleaseEvent(QMouseEvent *event)
{
m_isPressed = false;
return QWidget::mouseReleaseEvent(event);
}
void MyTitleBar::onButtonMinClicked()
{
this->window()->showMinimized();
}
void MyTitleBar::onButtonRestoreClicked()
{
QPoint windowPos;
QSize windowSize;
getRestoreInfo(windowPos, windowSize);
this->window()->setGeometry(QRect(windowPos, windowSize));
m_pButtonMax->setVisible(true);
m_pButtonRestore->setVisible(false);
}
void MyTitleBar::onButtonMaxClicked()
{
saveRestoreInfo(this->window()->pos(), QSize(this->window()->width(), this->window()->height()));
QRect desktopRect = QApplication::desktop()->availableGeometry();
QRect FactRect = QRect(desktopRect.x() - 3, desktopRect.y() - 3, desktopRect.width() + 6, desktopRect.height() + 6);
this->window()->setGeometry(FactRect);
m_pButtonRestore->setVisible(true);
m_pButtonMax->setVisible(false);
}
void MyTitleBar::onButtonCloseClicked()
{
this->window()->close();
}
widget.h添加代碼
#include "Include/titlebar.h"
private:
titlebar *m_pTitleBarMain;
widget.cpp添加代碼
titlebar::TitleInfo l_titleInfo;
l_titleInfo.m_FontSize = 22;
l_titleInfo.m_bkcolor = QColor(255, 255, 255);
l_titleInfo.m_Height = 46;
l_titleInfo.m_bmaxNeed = false;
l_titleInfo.m_Textcolor = QColor(255, 255, 255);
l_titleInfo.m_bminNeed = false;
l_titleInfo.m_bcloseNeed = true;
m_pTitleBarMain = new titlebar(nullptr, Qt::Dialog);
l_titleInfo.m_strTitle = QStringLiteral("Mytitle");
m_pTitleBarMain->SetTitleBarInfo(this, &l_titleInfo);
m_pTitleBarMain->setFixedSize(1200, 820);
m_pTitleBarMain->show();