1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Qt自定义标题栏可拖动修改窗口大小

Qt自定义标题栏可拖动修改窗口大小

时间:2024-05-19 15:51:37

相关推荐

Qt自定义标题栏可拖动修改窗口大小

文章目录

前言1.titlebar.h2.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; //按钮点击标志位QPointmovePoint; //鼠标移动需要记住的点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; //窗口高度boolisTitleBarResize;//标题栏是否可以改变大小boolisLeftPressDown;//判断左键是否按下Directiondir;//窗口大小改变时,记录改变方向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_H

2.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);

效果

总结

可根据自己需求添加删除按钮,调整标题栏大小。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。