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

文章目录

  • 前言
  • 效果
  • 代码
    • .pro文件
    • widget.h
    • widget.cpp
    • widget.ui
    • title.h
    • title.cpp
    • title.ui


前言

本次实验内容为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文件

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11
SOURCES += \main.cpp \title.cpp \widget.cppHEADERS += \title.h \widget.hFORMS += \title.ui \widget.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetRESOURCES += \src.qrc

widget.h

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

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "title.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;title *t1;};
#endif // WIDGET_H

widget.cpp

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

此句为设置无自带标题栏的属性,必须有这句话。
setWindowFlags(Qt::FramelessWindowHint);

新建一个垂直布局
QVBoxLayout* layout = new QVBoxLayout(this);

将自定义标题栏放置入垂直布局中去
layout->addWidget(t1);

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

widget.ui

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

title.h

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

#ifndef TITLE_H
#define TITLE_H#include <QWidget>
#include <QMouseEvent>namespace Ui {
class title;
}class title : public QWidget
{Q_OBJECTpublic:explicit title(QWidget *parent = nullptr);~title();void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);void mouseDoubleClickEvent(QMouseEvent *event);private slots:void onClicked();private:Ui::title *ui;QPoint m_start;  //起始点QPoint m_end;    //结束点bool m_leftButtonPressed;   //鼠标左键按下标记
};#endif // TITLE_H

title.cpp

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

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

#include "title.h"
#include "ui_title.h"
#include <QDebug>title::title(QWidget *parent) :QWidget(parent),ui(new Ui::title)
{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){//记录鼠标左键状态m_leftButtonPressed = true;//记录鼠标在屏幕中的位置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);//将鼠标在屏幕中的位置替换为新的位置m_start = event->globalPos();}
}void title::mouseReleaseEvent(QMouseEvent *event)
{if(event->button()==Qt::LeftButton){m_leftButtonPressed = false;}
}void title::mouseDoubleClickEvent(QMouseEvent *event)
{Q_UNUSED(event);ui->pushButton_3->click();
}void title::onClicked()
{QPushButton *pButton = qobject_cast<QPushButton *>(sender());QWidget *pWindow = this->window();if (pWindow->isTopLevel()){if(pButton == ui->pushButton){pWindow->showMinimized();}else if(pButton == ui->pushButton_2){pWindow->close();}else if(pButton == ui->pushButton_3){pWindow->isMaximized()?pWindow->showNormal():pWindow->showMaximized();}}
}

title.ui

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

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

注意:此处设置标题名称应通过右键设置样式表的方式设置其相关属性,不能通过右键“改变多文本信息”来设置其属性,否则标题栏鼠标拖动的效果将会失效

QWidget#widget
{background-color: rgb(98, 98, 98);
}
QLabel#label_2
{font: 16pt bold "楷体";font-weight:900;color:white;
}
QPushButton 
{border-style: solid;border-width: 0px;border-radius: 0px;background-color: rgba(223, 223, 223, 0);
}
QPushButton::focus{outline: none;}
QPushButton::hover 
{border-style: solid;border-width: 0px;border-radius: 0px;background-color: rgba(223, 223, 223, 150);
}

在这里插入图片描述

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

在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/175410.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NEFU数字图像处理(三)图像分割

一、图像分割的基本概念 1.1专有名词 前景和背景 在图像分割中&#xff0c;我们通常需要将图像分为前景和背景两个部分。前景是指图像中我们感兴趣、要分割出来的部分&#xff0c;背景是指和前景不相关的部分。例如&#xff0c;对于一张人物照片&#xff0c;人物就是前景&…

LIMZO-A-6/210开环控制比例插装阀控制器

LICZO-A-4/100、LIMZO-A-6/210、LIRZO-A-3/350、LIMZO-A-8/315、LICZO-A-3/100、LIRZO-A-6/210、LICZO-A-2/210二通数字式比例插装阀可分别执行: 压力补偿溢流和减压开环功能。此类阀有不同的型式可供选择:A型&#xff0c;与分体式放大器配合使用AEB型&#xff0c;带基本型集成…

Mybatis—XML配置文件、动态SQL

学习完Mybatis的基本操作之后&#xff0c;继续学习Mybatis—XML配置文件、动态SQL。 目录 Mybatis的XML配置文件XML配置文件规范XML配置文件实现MybatisX的使用 Mybatis动态SQL动态SQL-if条件查询 \<if\>与\<where\>更新员工 \<set\>小结 动态SQL-\<forea…

linux的使用学习(1)

Linux 修改root密码 1.以 root 用户或具有 sudo 权限的登录到 Linux 系统。 2.打终端&#xff0c;并执行以下命令以更改 root 用户的密码&#xff1a; sudo passwd root 3.然后&#xff0c;系统会要求你输入新的 root 密码。请注意&#xff0c;在输入密码时&#xff0c;终端界…

深入了解 Elasticsearch 8.1 中的 Script 使用

一、什么是 Elasticsearch Script&#xff1f; Elasticsearch 中的 Script 是一种灵活的方式&#xff0c;允许用户在查询、聚合和更新文档时执行自定义的脚本。这些脚本可以用来动态计算字段值、修改查询行为、执行复杂的条件逻辑等等。 二、支持的脚本语言有哪些 支持多种脚本…

JavaWeb——关于servlet种mapping地址映射的一些问题

6、Servlet 6.4、Mapping问题 一个Servlet可以指定一个映射路径 <servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pattern> </servlet-mapping>一个Servlet可以指定多个映射路径 <servlet-mapping>&…

音视频技术开发周刊 | 317

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 MIT惊人再证大语言模型是世界模型&#xff01;LLM能分清真理和谎言&#xff0c;还能被人类洗脑 MIT等学者的「世界模型」第二弹来了&#xff01;这次&#xff0c;他们证明…

中文编程工具免费版下载,中文开发语言工具免费版下载

中文编程工具免费版下载&#xff0c;中文开发语言工具免费版下载 中文编程工具开发的实际部分案例如下图 编程系统化课程总目录及明细&#xff0c;点击进入了解详情。 https://blog.csdn.net/qq_29129627/article/details/134073098?spm1001.2014.3001.5502

异步 AIMD 收敛

给出的一直都是同步 AIMD 收敛&#xff0c;所以简单&#xff0c;但不至于 bbr 单流情形退化成简陋。 给出一个异步 AIMD 收敛过程是必要的&#xff0c;可见&#xff0c;它同样是简洁优美的&#xff1a; 虽然我没有标注太多&#xff0c;它始终没有成为一团乱麻。 和同步 AIM…

softmax的高效CUDA编程和oneflow实现初步解析

本文参考了添加链接描述,其中oneflow实现softmax的CUDA编程源代码参考链接添加链接描述 关于softmax的解读以及CUDA代码实现可以参考本人之前编写的几篇文章添加链接描述,添加链接描述,添加链接描述 下面这个图片是之前本人实现的softmax.cu经过接入python接口,最终和pytor…

06、SpringCloud -- 订单详情界面实现

目录 订单详情界面实现需求&#xff1a;代码前端后端controllerservicemapperdomain 效果&#xff1a; 订单详情界面实现 需求&#xff1a; 现在的订单详情界面是这样的。需要获取订单的数据对这个详情页面进行渲染 代码 前端 后端 controller service mapper domain 日…

低功耗设计-ir drop的signoff corner怎么选择?

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 相关文章链接: Multi Voltage Flow笔记 有几个方向&#xff0c;看公司需求吧 1.功耗最差的&#xff1b; 2.tt的&#xff08;tt85 是比较接近芯片真实工作情况的&#xff09…

Hbase

目录 1 概述 1.1 HBase 数据模型 1.1.1 HBase 逻辑结构 1.1.2 HBase 物理存储结构 1.1.3 数据模型 1.2 HBase 基本架构 2 HBase 快速入门 2.1 HBase 安装部署 hadoop3.X和Hbase2.X不兼容问题&#xff1a; 2.2 基本操作 3 HBase API 3.1 环境准备 3.2 创建连接 3.2.1 单线程创建…

【数据结构】数组和字符串(七):特殊矩阵的压缩存储:三元组表的转置、加法、乘法操作

文章目录 4.2.1 矩阵的数组表示4.2.2 特殊矩阵的压缩存储a. 对角矩阵的压缩存储b~c. 三角、对称矩阵的压缩存储d. 稀疏矩阵的压缩存储——三元组表4.2.3三元组表的转置、加法、乘法、操作转置加法乘法算法测试实验结果代码整合 4.2.1 矩阵的数组表示 【数据结构】数组和字符串…

github搜索技巧探索

毕设涉及到推荐系统&#xff0c;那么就用搜索推荐系统相关资料来探索一下GitHub的搜搜技巧 文章目录 1. 基础搜索2. 限定在特定仓库搜索3. 按照语言搜索4. 按照star数量搜索5. 搜索特定用户/组织的仓库6. 查找特定文件或路径7. 按时间搜索8. 搜索不包含某个词的仓库9. 搜索特定…

Spring MVC的常用注解(接收请求数据篇)

目录 RequestMapping 例子&#xff1a; RequestMapping 支持什么类型的请求 使 RequestMapping 只支持特定的类型 RestController 通过 HTTP 请求传递参数给后端 1.传递单个参数 注意使⽤基本类型来接收参数的情况 2.传递多个参数 3.传递对象 4.RequestParam 后端参数…

【教3妹学编辑-算法题】每棵子树内缺失的最小基因值

3妹&#xff1a;“太阳当空照&#xff0c;花儿对我笑&#xff0c;小鸟说早早早&#xff0c;你为什么背上炸药包” 2哥 :3妹&#xff0c;什么事呀这么开发。 3妹&#xff1a;2哥你看今天的天气多好啊&#xff0c;阳光明媚、万里无云、秋高气爽&#xff0c;适合秋游。 2哥&#x…

超全整理,Jmeter性能测试-脚本error报错排查/分布式压测(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能脚本error报错…

【JavaSE专栏57】深度解析Java中的this和super关键字:用途、差异和实际应用

深度解析Java中的this和super关键字&#xff1a;用途、差异和实际应用 摘要引言1. this关键字1.1 什是this关键字&#xff1f; &#x1f914;使用 this 解决成员变量和参数之间的歧义&#xff1a;在构造方法中调用其他构造方法&#xff1a;1.3 引用成员变量和方法 &#x1f3af…

使用内网穿透工具进行支付宝沙箱环境支付的SDK接口远程测试

Java支付宝沙箱环境支付&#xff0c;SDK接口远程调试【内网穿透】 1.测试环境 MavenSpring bootJdk 1.8 2.本地配置 获取支付宝支付Java SDK,maven项目可以选择maven版本,普通java项目可以在GitHub下载,这里以maven为例 SDK下载地址&#xff1a;https://doc.open.alipay.com…