Qt自定义标题栏可拖动修改窗口大小
生活随笔
收集整理的這篇文章主要介紹了
Qt自定义标题栏可拖动修改窗口大小
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 前言
- 1.titlebar.h
- 2.titlebar.cpp
- 應用
- 效果
- 總結
前言
記錄下Qt的自定義標題欄。
提示:以下是本篇文章正文內容,下面案例可供參考
1.titlebar.h
代碼如下(示例):
#ifndef TITLEBAR_H #define TITLEBAR_H#include <QLabel> #include <QFrame> #include <QMovie> #include <QFont> #include <QIcon> #include <QStyle> #include <QDebug> #include <QFrame> #include <QTimer> #include <QObject> #include <QListView> #include <QShortcut> #include <QComboBox> #include <QPushButton> #include <QHBoxLayout> #include <QMouseEvent> #include <QVBoxLayout> #include <QMessageBox> #include <QApplication> #include <QDesktopWidget> #include <QPropertyAnimation> #include <QParallelAnimationGroup> #include <QGraphicsDropShadowEffect> #include "windows.h"#define PADDING 5#ifndef SAFEDELETE #define SAFEDELETE(pointer) \ { \if(pointer) \{ \delete pointer; \} \pointer = NULL; \ } #endifnamespace TITLEBAR {enum WIDGETBYTTONTYPE{MAXWIDGET, //去掉最大化按鈕MINWIDGET, //去掉最小化按鈕CloseWIDGET, //去掉關閉按鈕ALLWIDGET, //去掉除關閉按鈕外的所有按鈕NOBUTTON, //去除所有按鈕}; }class TitleBar : public QFrame {Q_OBJECTpublic:explicit TitleBar(QWidget *parentWidget = nullptr);enum Direction { UP = 0, LEFT, RIGHT, LEFTTOP, RIGHTTOP, NONE };void initData();void initBotton(); //初始化按鈕void initConnect(); //初始化值void setWindowTitle(const QString &title); //設置標題void setWindowIcon(const QString &icon); //設置圖標(為空時隱藏圖標)void subWindowButton(const int &type); //設置按鈕void Shadow_Warning(); //設置陰影void RemoveMaxMinButton(); //移除最大最小按鈕void Set_MaximizeFlag(); //設置雙擊標題欄是否可以最大、最小化void Set_MouseShapeFlag(bool MouseShape); //設置標題欄是否可以改變大小bool FileIsExist(QString strFile); //文件是否存在void SetTitleLabelTextColor(int R,int G,int B); //修改標題顯示文字顏色const static int TITLEBARHEIGHT = 30; //標題欄高度const static int CONTROLWIDTH = 30; //控件寬度QRectF boundingRect() const;QRectF leftBorder() const;QRectF rightBorder() const;QRectF topBorder() const;QRectF bottomBorder() const;void setMousePressCursorShape(const QPointF& pt, bool isShow = true);public slots:void showMax(); //最大化窗口void showMin(); //最小化窗口void showClose(); //關閉窗口void set_ChildWindowColor(int R,int G,int B); //設置標題欄背景色void ModifyTitleBarTip(); //修改標題欄按鈕提示語言signals:void send_close(); //發送關閉信號void send_showToolbar(); //發送顯示/隱藏工具欄信號private slots:private:QPushButton *maxButton; //最大化按鈕QPushButton *minButton; //最小化按鈕QPushButton *closeButton; //關閉按鈕QLabel *imgLabel; //圖片框QLabel *titleLabel; //標題名QWidget *parentWidget; //父窗口bool mousePress; //按鈕點擊標志位QPoint movePoint; //鼠標移動需要記住的點int switchFlag;int MaximizeFlag; //雙擊是否最大化int IsShow_Toolbar; //顯示隱藏工具欄int Original_window_x; //窗口x坐標int Original_window_y; //窗口y坐標int Original_window_Mywidth; //窗口寬度int Original_window_Myheight; //窗口高度bool isTitleBarResize; //標題欄是否可以改變大小bool isLeftPressDown; //判斷左鍵是否按下Direction dir; //窗口大小改變時,記錄改變方向private:void mousePressEvent(QMouseEvent * event); //鼠標點擊事件void mouseReleaseEvent(QMouseEvent *event); //鼠標釋放事件void mouseMoveEvent(QMouseEvent * event); //鼠標移動事件void mouseDoubleClickEvent(QMouseEvent *event); //鼠標雙擊事件bool eventFilter(QObject *obj, QEvent *event);void paintEvent(QPaintEvent *event); //繪制事件 };#endif // TITLEBAR_H2.titlebar.cpp
代碼如下(示例):
#include "titlebar.h"#include <QSizeGrip>/*************************** 構造函數 ***************************/ TitleBar::TitleBar(QWidget *parent) : QFrame(parent) {//設置父類窗口parentWidget = parent;//初始化參數initData();//初始化按鈕initBotton();//初始化initConnect();//設置標題欄背景色set_ChildWindowColor(70, 70, 70);//設置標題欄顯示文字顏色SetTitleLabelTextColor(255, 255, 255);//重置窗口大小resize(parent->width(), TITLEBARHEIGHT);setFixedHeight(TITLEBARHEIGHT);//設置陰影//Shadow_Warning(); }void TitleBar::initData() {switchFlag = 1;MaximizeFlag = 0;isTitleBarResize = false;IsShow_Toolbar = 1;this->setMouseTracking(true);this->setAttribute(Qt::WA_Hover, true);this->installEventFilter(this);isLeftPressDown = false;this->dir = NONE; } void TitleBar::initBotton() {//最大化按鈕設置圖標maxButton = new QPushButton(this);maxButton->setFocusPolicy(Qt::NoFocus);maxButton->setIcon(QPixmap("style/icons/max.png"));//最小化按鈕設置圖標minButton = new QPushButton(this);minButton->setFocusPolicy(Qt::NoFocus);minButton->setIcon(QPixmap("style/icons/min.png"));//關閉按鈕設置圖標closeButton = new QPushButton(this);closeButton->setShortcut(tr("Ctrl+w"));closeButton->setFocusPolicy(Qt::NoFocus);closeButton->setIcon(QPixmap("style/icons/close.png"));//設置標簽imgLabel = new QLabel(this);titleLabel = new QLabel(this);titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);//設置控件大小imgLabel->setFixedSize(CONTROLWIDTH - 5, CONTROLWIDTH - 5);imgLabel->setScaledContents(true);titleLabel->setMinimumSize(120, TITLEBARHEIGHT);minButton->setFixedSize(CONTROLWIDTH, CONTROLWIDTH);maxButton->setFixedSize(CONTROLWIDTH, CONTROLWIDTH);closeButton->setFixedSize(CONTROLWIDTH, CONTROLWIDTH);//設置控件圖標大小minButton->setIconSize(QSize(CONTROLWIDTH, CONTROLWIDTH));maxButton->setIconSize(QSize(CONTROLWIDTH, CONTROLWIDTH));closeButton->setIconSize(QSize(CONTROLWIDTH, CONTROLWIDTH));//設置鼠標移至按鈕上的提示信息ModifyTitleBarTip();//設置布局QHBoxLayout *hBoxLayout = new QHBoxLayout;hBoxLayout->addSpacing(5);hBoxLayout->addWidget(imgLabel);hBoxLayout->addSpacing(5);hBoxLayout->addWidget(titleLabel);hBoxLayout->addStretch();hBoxLayout->addSpacing(5);hBoxLayout->addWidget(minButton);hBoxLayout->addWidget(maxButton);hBoxLayout->addWidget(closeButton);hBoxLayout->setSpacing(0);hBoxLayout->setContentsMargins(0, 0, 2, 0);this->setLayout(hBoxLayout); }/*************************** 設置標題 ***************************/ void TitleBar::setWindowTitle(const QString &title) {QFont myFont;//設置文字大小myFont.setPointSize(12);//設置文字字體myFont.setFamily(qApp->font().family());titleLabel->setFont(myFont);titleLabel->setText(title); }/*************************** 設置圖標 ***************************/ void TitleBar::setWindowIcon(const QString &icon) {if (icon.isEmpty())imgLabel->hide();elseimgLabel->setPixmap(QPixmap(icon)); }/*************************** 設置標題欄不需要顯示的按鈕 ***************************/ void TitleBar::subWindowButton(const int &type) {if(type == TITLEBAR::MINWIDGET){SAFEDELETE(minButton);}else if(type == TITLEBAR::MAXWIDGET){SAFEDELETE(maxButton);}else if(type == TITLEBAR::CloseWIDGET){SAFEDELETE(closeButton);}else if(type == TITLEBAR::ALLWIDGET){SAFEDELETE(minButton);SAFEDELETE(maxButton);}else if (type == TITLEBAR::NOBUTTON){SAFEDELETE(minButton);SAFEDELETE(maxButton);SAFEDELETE(closeButton);} }void TitleBar::Shadow_Warning() {//窗口添加陰影效果QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect;shadow_effect->setOffset(0, 4);shadow_effect->setColor(Qt::gray);shadow_effect->setBlurRadius(6);this->setGraphicsEffect(shadow_effect);#if 0//實現毛玻璃效果QGraphicsBlurEffect* ef = new QGraphicsBlurEffect;ef->setBlurRadius(1.5);ef->setBlurHints(QGraphicsBlurEffect::AnimationHint);this->setGraphicsEffect(ef); #endif }//移除最大最小按鈕 void TitleBar::RemoveMaxMinButton() {subWindowButton(TITLEBAR::ALLWIDGET); }//設置雙擊標題欄是否可以最大、最小化 void TitleBar::Set_MaximizeFlag() {MaximizeFlag = 1; } //文件是否存在 bool TitleBar::FileIsExist(QString strFile) {QFile tempFile(strFile);return tempFile.exists(); } //修改標題顯示文字顏色 void TitleBar::SetTitleLabelTextColor(int R,int G,int B) {titleLabel->setStyleSheet(QString("QLabel{background-color:transparent;color:rgb(%1,%2,%3);outline: none;border:none;qproperty-alignment: 'AlignVCenter | AlignLeft';}").arg(R).arg(G).arg(B)); }/*************************** 初始化 ***************************/ void TitleBar::initConnect() {//設置樣式表minButton->setStyleSheet("QPushButton{background-color:transparent;outline: none;border:none;}QPushButton:hover{padding-left:6px;padding-top:6px;}");maxButton->setStyleSheet("QPushButton{background-color:transparent;outline: none;border:none;}QPushButton:hover{padding-left:6px;padding-top:6px;}");closeButton->setStyleSheet("QPushButton{background-color:transparent;outline: none;border:none;border-radius: 0px;}QPushButton:hover{padding-left:6px;padding-top:6px;background-color:rgb(237,28,36);}");//連接信號與槽connect(minButton, SIGNAL(clicked(bool)), this, SLOT(showMin()));connect(maxButton, SIGNAL(clicked(bool)), this, SLOT(showMax()));connect(closeButton, SIGNAL(clicked(bool)), this, SLOT(showClose())); }/*************************** 最大化 ***************************/ void TitleBar::showMax() {if(parentWidget->geometry() == QApplication::desktop()->availableGeometry()) //判斷是否是全屏{maxButton->setIcon(QPixmap("style/icons/max.png"));//退出全屏時設置為原窗口的坐標位置和尺寸大小parentWidget->setGeometry(Original_window_x, Original_window_y, Original_window_Mywidth, Original_window_Myheight);}else{//但不是全屏時獲取原窗口的坐標和尺寸Original_window_x = parentWidget->geometry().x();Original_window_y = parentWidget->geometry().y();Original_window_Mywidth = parentWidget->geometry().width();Original_window_Myheight = parentWidget->geometry().height();maxButton->setIcon(QPixmap("style/icons/normal.png"));parentWidget->setGeometry(QApplication::desktop()->availableGeometry()); //這種設置不會全屏遮擋任務欄} }/*************************** 最小化 ***************************/ void TitleBar::showMin() {parentWidget->showMinimized(); }/*************************** 發送關閉信號給主窗口 ***************************/ void TitleBar::showClose() {emit send_close(); }void TitleBar::set_ChildWindowColor(int R,int G,int B) {//設置背景色setStyleSheet(QString("QFrame{background-color:rgb(%1,%2,%3);outline: none;border:none;}").arg(R).arg(G).arg(B)); }//修改標題欄按鈕提示語言 void TitleBar::ModifyTitleBarTip() {//設置鼠標移至按鈕上的提示信息minButton->setToolTip(tr(u8"最小化"));maxButton->setToolTip(tr(u8"最大化"));closeButton->setToolTip(tr(u8"關閉")); }/*************************** 鼠標點擊 ***************************/ void TitleBar::mousePressEvent(QMouseEvent *event) {if(event->button() == Qt::LeftButton){isLeftPressDown = true;if (isTitleBarResize)setMousePressCursorShape(event->pos());if (dir != NONE) {this->mouseGrabber();}else {movePoint = event->globalPos() - parentWidget->pos();}} }/************************** 鼠標釋放 ***************************/ void TitleBar::mouseReleaseEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton) {isLeftPressDown = false;if (dir != NONE) {dir = NONE;this->releaseMouse();this->setCursor(QCursor(Qt::ArrowCursor));}} }/************************** 鼠標移動 **************************/ void TitleBar::mouseMoveEvent(QMouseEvent *event) {if(parentWidget->geometry() == QApplication::desktop()->availableGeometry()){//判斷當前是全屏就不允許拖動窗口}else{//當前不是全屏可以拖動窗口QPoint gloPoint = event->globalPos();QRect rect = parentWidget->rect();QPoint tl = mapToGlobal(rect.topLeft());QPoint rb = mapToGlobal(rect.bottomRight());if (!isLeftPressDown) {if (isTitleBarResize)setMousePressCursorShape(gloPoint);}else {if (dir != NONE) {QRect rMove(tl, rb);switch (dir) {case LEFT:if (rb.x() - gloPoint.x() <= parentWidget->minimumWidth())rMove.setX(tl.x());elserMove.setX(gloPoint.x());break;case RIGHT:rMove.setWidth(gloPoint.x() - tl.x());break;case UP:if (rb.y() - gloPoint.y() <= parentWidget->minimumHeight())rMove.setY(tl.y());elserMove.setY(gloPoint.y());break;case LEFTTOP:if (rb.x() - gloPoint.x() <= parentWidget->minimumWidth())rMove.setX(tl.x());elserMove.setX(gloPoint.x());if (rb.y() - gloPoint.y() <= parentWidget->minimumHeight())rMove.setY(tl.y());elserMove.setY(gloPoint.y());break;case RIGHTTOP:rMove.setWidth(gloPoint.x() - tl.x());if (rb.y() - gloPoint.y() <= parentWidget->minimumHeight())rMove.setY(tl.y());elserMove.setY(gloPoint.y());break;default:break;}parentWidget->setGeometry(rMove);}else {QPoint movePos = event->globalPos();parentWidget->move(movePos - movePoint);event->accept();}}} }/************************** 鼠標雙擊 **************************/ void TitleBar::mouseDoubleClickEvent(QMouseEvent *event) {if(event->button() == Qt::LeftButton){if(MaximizeFlag == 1){int x = event->x();int y = event->y();if((x > 0 && x < parentWidget->width()) && (y > 0 && y < TITLEBARHEIGHT)) //如果雙擊的范圍在標題欄的范圍之內{showMax(); //調用全屏、退出全屏函數}}} }bool TitleBar::eventFilter(QObject * obj, QEvent * event) {if (obj == this){if (event->type() == QMouseEvent::HoverEnter){QMouseEvent *_mouseEvent = static_cast<QMouseEvent *>(event);if (isTitleBarResize)setMousePressCursorShape(_mouseEvent->pos(), false);}if (event->type() == QMouseEvent::HoverMove){QMouseEvent *_mouseEvent = static_cast<QMouseEvent *>(event);if (!isLeftPressDown){if (isTitleBarResize)setMousePressCursorShape(_mouseEvent->pos(), false);}}if (event->type() == QMouseEvent::HoverLeave){if (isTitleBarResize)unsetCursor();}}return QFrame::eventFilter(obj, event); }void TitleBar::Set_MouseShapeFlag(bool MouseShape) {isTitleBarResize = MouseShape; }QRectF TitleBar::boundingRect() const {return QRectF(QPointF(0, 0), geometry().size()); }QRectF TitleBar::leftBorder() const {return QRectF(0, 0, PADDING, boundingRect().height()); }QRectF TitleBar::rightBorder() const {return QRectF(boundingRect().width() - PADDING, 0, PADDING, boundingRect().height()); }QRectF TitleBar::topBorder() const {return QRectF(0, 0, boundingRect().width(), PADDING); }QRectF TitleBar::bottomBorder() const {return QRectF(0, boundingRect().height() - PADDING, boundingRect().width(), PADDING); }void TitleBar::setMousePressCursorShape(const QPointF& pt, bool isShow) {QCursor cursor = Qt::ArrowCursor;if (rightBorder().contains(pt) && topBorder().contains(pt)) // 右上角{if(isShow)dir = RIGHTTOP;this->setCursor(QCursor(Qt::SizeBDiagCursor));}else if (leftBorder().contains(pt) && topBorder().contains(pt)) // 左上角{if (isShow)dir = LEFTTOP;this->setCursor(QCursor(Qt::SizeFDiagCursor));}else if (rightBorder().contains(pt)) // 右邊{if (isShow)dir = RIGHT;this->setCursor(QCursor(Qt::SizeHorCursor));}else if (leftBorder().contains(pt)) // 左邊{if (isShow)dir = LEFT;this->setCursor(QCursor(Qt::SizeHorCursor));}else if (topBorder().contains(pt)) // 上邊{if (isShow)dir = UP;this->setCursor(QCursor(Qt::SizeVerCursor));}else{if (isShow)dir = NONE;this->setCursor(QCursor(isLeftPressDown ? Qt::SizeAllCursor : Qt::ArrowCursor));} }// 繪制事件中設置標題欄寬度跟隨父窗口寬度變化尺寸 void TitleBar::paintEvent(QPaintEvent *event) {if (this->width() != parentWidget->width()){this->setFixedWidth(parentWidget->width());}QFrame::paintEvent(event); }應用
//自定義標題欄{Main_InterfaceTitleBar = new TitleBar(this); //在.h頭文件中TitleBar *Main_InterfaceTitleBarsetWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); //設置為無邊框connect(Main_InterfaceTitleBar, &TitleBar::send_close, this, [=]() {close();}); //一般窗口就是關閉,主界面或登錄界面就是退出軟件Main_InterfaceTitleBar->Set_MaximizeFlag(); //設置是否有最大最小化按鈕Main_InterfaceTitleBar->setFixedHeight(40); //設置標題欄高度Main_InterfaceTitleBar->Set_MouseShapeFlag(true); //設置是否可以改變窗口大小Main_InterfaceTitleBar->setWindowIcon(":/trayIcon.png"); //這里根據自己的圖標路徑填寫Main_InterfaceTitleBar->setWindowTitle(tr("圖像拼接處理器")); //設置標題欄標題}//布局情況很多種,標題欄只是顯示在父窗口最上面的位置,具體怎么調整根據自己的布局來設置QVBoxLayout *vlayout = new QVBoxLayout;vlayout->addWidget(LargeScreenTitleBar);vlayout->addLayout(...);vlayout->addWidget(...);vlayout->addWidget(...);vLayout->setContentsMargins(0, 0, 0, 0);setLayout(vlayout);效果
總結
可根據自己需求添加刪除按鈕,調整標題欄大小。
總結
以上是生活随笔為你收集整理的Qt自定义标题栏可拖动修改窗口大小的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue导入excel进度条_在vue中导
- 下一篇: 采购流程图怎么画?手把手教你绘制采购流程