0


Qt 自定义标题栏,最小化、最大化、关闭窗口,双击最大化,鼠标拖动等效果实现

文章目录


前言

本次实验内容为Qt自定义标题栏,最小化、最大化、关闭窗口,双击最大化,鼠标拖动等界面软件的基本常规操作。

我们在做一个软件界面的时候,有时需要其任务栏显示一些文本、图片甚至一些自定义控件的内容,但是通过Qt自动创建的窗口类仅自带系统风格的标题栏,往往并不能满足我们的自定义设计需求。

在这种情况下,需要用Qt设计自定义标题栏内的相关内容。本篇博客记录本人实现这一功能的前后代码过程,并不一定是标准方式,仅作一个记录,在后面项目用的时候进行查阅。


效果

主要实现的窗口操作为以下5点内容:
(1)在“灰色”区域,即自定义标题栏区域内,最左侧为logo图标,往右为软件名称标题,最右边分别外三个按钮,依次为“最小化”、“最大化”、“关闭”按钮;
(2)标题栏区域(包含logo以及名称标题上)拖动鼠标,实现整个窗口的拖动功能,蓝色区域拖拽鼠标,不会拖动整个窗口;
(3)标题栏区域(包含logo以及名称标题上)双击鼠标左键,实现最大化、还原窗口的操作;
(4)鼠标移动至“最小化”、“最大化”、“关闭”按钮上会改变按钮的背景色;
(5)鼠标单击最小化、最大化、关闭按钮,嫩实现相应的窗口操作功能。
下图为自定义标题栏的软件界面效果。
在这里插入图片描述

代码

建立Qt工程文件,自动生成widget.h,widget.cpp以及widget.ui,再新建一个Qt 的Ui界面类,即title类,生成title.h,title.cpp,title.ui三个文件

widget类为整体窗体类,用于最底层展示窗口,title类为自定义标题栏类。

整个工程文件夹下内容如下图所示:
在这里插入图片描述

.pro文件

  1. QT += core gui
  2. greaterThan(QT_MAJOR_VERSION,4): QT += widgets
  3. CONFIG += c++11
  4. SOURCES += \
  5. main.cpp \
  6. title.cpp \
  7. widget.cpp
  8. HEADERS += \
  9. title.h \
  10. widget.h
  11. FORMS += \
  12. title.ui \
  13. widget.ui
  14. #Default rules for deployment.
  15. qnx: target.path =/tmp/$${TARGET}/bin
  16. else: unix:!android: target.path =/opt/$${TARGET}/bin
  17. !isEmpty(target.path): INSTALLS += target
  18. RESOURCES += \
  19. src.qrc

widget.h

在widget.h文件中将title类的头文件title.h包含进去,并声明一个title类指针。

  1. #ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include"title.h"
  2. QT_BEGIN_NAMESPACE
  3. namespace Ui {classWidget;}
  4. QT_END_NAMESPACE
  5. classWidget:publicQWidget{
  6. Q_OBJECT
  7. public:Widget(QWidget *parent =nullptr);~Widget();private:
  8. Ui::Widget *ui;
  9. title *t1;};#endif// WIDGET_H

widget.cpp

在Widget构造函数中,首先建立ui界面,设置窗口的无边框属性,实例化一个title对象,并将该对象放置到窗体的对象树上。

此句为设置无自带标题栏的属性,必须有这句话。

  1. setWindowFlags(Qt::FramelessWindowHint);

新建一个垂直布局

  1. QVBoxLayout* layout = new QVBoxLayout(this);

将自定义标题栏放置入垂直布局中去

  1. layout->addWidget(t1);
  1. #include"widget.h"#include"ui_widget.h"#include<QVBoxLayout>Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
  2. ui->setupUi(this);setWindowFlags(Qt::FramelessWindowHint);//隐藏标题栏(无边框)
  3. t1 =newtitle(this);
  4. t1->setParent(this);//新建一个垂直布局,并将title对象、ui->stackedWidget放置入该垂直布局中去
  5. QVBoxLayout* layout =newQVBoxLayout(this);
  6. layout->addWidget(t1);
  7. layout->addWidget(ui->stackedWidget);//设置垂直布局间隙
  8. layout->setSpacing(0);
  9. layout->setMargin(0);}Widget::~Widget(){delete ui;}

widget.ui

ui界面中,在Widget中放置一个QStackedWidget用于后续工作,不需要在此处进行布局。
在这里插入图片描述

title.h

在widget.h文件中将title类的头文件title.h包含进去,并声明一个title类指针。

  1. #ifndefTITLE_H#defineTITLE_H#include<QWidget>#include<QMouseEvent>namespace Ui {classtitle;}classtitle:publicQWidget{
  2. Q_OBJECT
  3. public:explicittitle(QWidget *parent =nullptr);~title();voidmousePressEvent(QMouseEvent *event);voidmouseMoveEvent(QMouseEvent *event);voidmouseReleaseEvent(QMouseEvent *event);voidmouseDoubleClickEvent(QMouseEvent *event);private slots:voidonClicked();private:
  4. Ui::title *ui;
  5. QPoint m_start;//起始点
  6. QPoint m_end;//结束点bool m_leftButtonPressed;//鼠标左键按下标记};#endif// TITLE_H

title.cpp

在title构造函数中,首先建立ui界面,接着连接鼠标点击title中的三个QPushButton时产生的信号及对应操作的槽函数。
此处将三个按钮的点击信号连接至同一个槽函数,在槽函数中判断点击信号的发送对象,然后作出相应操作。

重写mousePressEvent、mouseMoveEvent、mouseMoveEvent、mouseDoubleClickEvent四个鼠标事件

  1. #include"title.h"#include"ui_title.h"#include<QDebug>
  2. title::title(QWidget *parent):QWidget(parent),ui(new Ui::title){
  3. ui->setupUi(this);connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(onClicked()));connect(ui->pushButton_2,SIGNAL(clicked(bool)),this,SLOT(onClicked()));connect(ui->pushButton_3,SIGNAL(clicked(bool)),this,SLOT(onClicked()));}title::~title(){delete ui;}void title::mousePressEvent(QMouseEvent *event){//鼠标左键按下事件if(event->button()==Qt::LeftButton){//记录鼠标左键状态
  4. m_leftButtonPressed =true;//记录鼠标在屏幕中的位置
  5. m_start = event->globalPos();// qDebug()<<QString::fromLocal8Bit("左键被按下了");}}void title::mouseMoveEvent(QMouseEvent *event){if(m_leftButtonPressed){//将父窗体移动到父窗体原来的位置加上鼠标移动的位置:event->globalPos()-m_start//this->window()获取this->window()->move(this->window()->geometry().topLeft()+event->globalPos()-m_start);//将鼠标在屏幕中的位置替换为新的位置
  6. m_start = event->globalPos();}}void title::mouseReleaseEvent(QMouseEvent *event){if(event->button()==Qt::LeftButton){
  7. m_leftButtonPressed =false;}}void title::mouseDoubleClickEvent(QMouseEvent *event){Q_UNUSED(event);
  8. ui->pushButton_3->click();}void title::onClicked(){
  9. QPushButton *pButton =qobject_cast<QPushButton *>(sender());
  10. QWidget *pWindow =this->window();if(pWindow->isTopLevel()){if(pButton == ui->pushButton){
  11. pWindow->showMinimized();}elseif(pButton == ui->pushButton_2){
  12. pWindow->close();}elseif(pButton == ui->pushButton_3){
  13. pWindow->isMaximized()?pWindow->showNormal():pWindow->showMaximized();}}}

title.ui

title.ui界面中,在title中放置两个QLabel三个QPushButton,两个QLabel分别用于展示logo及软件标题名称,三个QPushButton为最小化、最大化以及关闭操作。
在这里插入图片描述

在右侧的对象树上,顶层对象上右键改变样式表,添加如下的样式表,直接设置title类中各个子对象的样式。

注意:此处设置标题名称应通过右键设置样式表的方式设置其相关属性,

  1. 不能通过右键“改变多文本信息”来设置其属性

,否则标题栏鼠标拖动的效果将会

  1. 失效

  1. QWidget#widget
  2. {
  3. background-color:rgb(98,98,98);}
  4. QLabel#label_2
  5. {
  6. font:16pt bold "楷体";
  7. font-weight:900;
  8. color:white;}
  9. QPushButton
  10. {
  11. border-style: solid;
  12. border-width:0px;
  13. border-radius:0px;
  14. background-color:rgba(223,223,223,0);}
  15. QPushButton::focus{outline: none;}
  16. QPushButton::hover
  17. {
  18. border-style: solid;
  19. border-width:0px;
  20. border-radius:0px;
  21. background-color:rgba(223,223,223,150);}

在这里插入图片描述

直接在QtCreator右下方设置QPushButton类相关属性,这里的pushButton_3比较特殊,它具有两个状态,一是“还原”状态,二是“最大化”状态,在QAbstractButton里有icon的属性,Normal Off状态下选择“最大化.png”,Active On状态下选择“还原.png”,并且需要勾选“checkabel”复选框

在这里插入图片描述

当然,这里的相关设置也可以通过代码实现,我个人还是比较习惯于直接在Ui界面内设置了,比较方便。

标签: qt ui

本文转载自: https://blog.csdn.net/wang_chao118/article/details/126582831
版权归原作者 wang_chao118 所有, 如有侵权,请联系我们删除。

“Qt 自定义标题栏,最小化、最大化、关闭窗口,双击最大化,鼠标拖动等效果实现”的评论:

还没有评论