QT5.14.2解锁Qt自定义标题栏的无限可能,一键拥有与众不同的个性窗口!


在现代化的软件设计中,个性化和美观是应用程序界面不可或缺的元素。而传统的Qt窗口往往风格单一,标题栏固定死板,这严重限制了界面的灵活性和视觉体验。有没有一种方法,可以摆脱这些束缚,为我们的Qt应用注入无限活力?今天,我们就来探索自定义Qt标题栏的奥秘,打造属于你自己的曲线玲珑、别具一格的窗口王冠!


一、Qt自定义标题栏的优势

相比于使用Qt默认的标题栏,自定义标题栏有以下显著优势:

  1. 无限个性化:可自由设计标题栏的外观、布局、控件等,实现与众不同的风格。

  2. 跨平台统一:在不同操作系统下,标题栏界面保持一致,提升应用的整体性。

  3. 功能扩展性强:可方便地添加自定义按钮、搜索框等新功能,提高用户体验。


二、标题栏组件拆解

要实现自定义标题栏,我们需要自行构建其各个组成部分,包括:

  • 标题文字:用于显示应用程序名称或当前窗口标题
  • 窗口控制按钮:最小化、最大化/恢复、关闭按钮
  • 拖动区域:用于实现整个窗口的拖动
  • 其他功能按钮:比如菜单按钮、搜索框等

下面就让我们一一部署这些组件吧。


三、标题栏组件实现

1、标题栏基本界面搭建

我们首先创建一个无边框的Qt窗口,在其上绘制标题栏:

QWidget *window = new QWidget;
window->setWindowFlags(Qt::FramelessWindowHint); //设置无边框

然后通过样式表设置标题栏的基本外观:

#titlebar {background-color: #323232;
}#titlebar QLabel {color: white; font-weight: bold;
}

在代码中,我们使用QPushButton、QLabel等Qt控件来创建标题文字、最小化/最大化/关闭按钮:

// 标题文字
auto titleLabel = new QLabel(this);
titleLabel->setText("My App");// 最小化按钮
auto minimizeBtn = new QPushButton(this);
minimizeBtn->setIcon(style->standardIcon(QStyle::SP_TitleBarMinButton));
connect(minimizeBtn, &QPushButton::clicked, this, &CustomTitleBar::showMinimized);// 其他按钮...

2、实现拖动功能

我们需要在标题栏捕获鼠标的按下、移动、释放事件,根据鼠标的位移来移动整个窗口。

// 在mousePressEvent中记录初始位置
m_startPos = event->globalPos();// 在mouseMoveEvent中根据位移调整窗口位置 
move(geometry().topLeft() + event->globalPos() - m_startPos);// 在mouseReleaseEvent中重置状态

3、实现双击最大化/恢复

通过重写mouseDoubleClickEvent,当双击标题栏时,我们切换窗口的最大化/恢复状态:

void CustomTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{if(window()->isMaximized())window()->showNormal();elsewindow()->showMaximized();
}

四、实战案例

这里给出自定义标题栏的完整源码:

titlebar.h

#ifndef TITLEBAR_H
#define TITLEBAR_H#include <QWidget>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>class TitleBar : public QWidget
{Q_OBJECTpublic:explicit TitleBar(QWidget *parent = nullptr);void setWindowTitle(const QString &title);void setWindowIcon(const QIcon &icon);protected:void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;void mouseDoubleClickEvent(QMouseEvent *event) override;private slots:void onButtonClicked();private:QLabel *m_titleLabel;QPushButton *m_minimizeButton;QPushButton *m_maximizeButton;QPushButton *m_closeButton;QPoint m_startPos;bool m_isMousePressed;
};#endif // TITLEBAR_H

titlebar.cpp:

#include "titlebar.h"#include <QHBoxLayout>
#include <QMouseEvent>
#include <QApplication>
#include <QStyle>TitleBar::TitleBar(QWidget *parent): QWidget(parent), m_isMousePressed(false)
{// 标题文字m_titleLabel = new QLabel(this);m_titleLabel->setStyleSheet("color: white; font-weight: bold;");// 最小化按钮m_minimizeButton = new QPushButton(this);m_minimizeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarMinButton));connect(m_minimizeButton, &QPushButton::clicked, this, &TitleBar::onButtonClicked);// 最大化按钮m_maximizeButton = new QPushButton(this);m_maximizeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarMaxButton));connect(m_maximizeButton, &QPushButton::clicked, this, &TitleBar::onButtonClicked);// 关闭按钮m_closeButton = new QPushButton(this);m_closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));connect(m_closeButton, &QPushButton::clicked, this, &TitleBar::onButtonClicked);// 布局QHBoxLayout *layout = new QHBoxLayout(this);layout->addWidget(m_titleLabel);layout->addWidget(new QWidget(), 1); // 用于占据中间空间layout->addWidget(m_minimizeButton);layout->addWidget(m_maximizeButton);layout->addWidget(m_closeButton);layout->setContentsMargins(5, 5, 5, 5);// 设置标题栏样式setStyleSheet("background-color: #323232;");
}void TitleBar::setWindowTitle(const QString &title)
{m_titleLabel->setText(title);
}void TitleBar::setWindowIcon(const QIcon &icon)
{m_titleLabel->setPixmap(icon.pixmap(16, 16));
}void TitleBar::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) {m_isMousePressed = true;m_startPos = event->globalPos();}
}void TitleBar::mouseMoveEvent(QMouseEvent *event)
{if (m_isMousePressed) {QPoint delta = event->globalPos() - m_startPos;window()->move(window()->pos() + delta);}
}void TitleBar::mouseReleaseEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) {m_isMousePressed = false;}
}void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{Q_UNUSED(event)if (window()->isMaximized()) {window()->showNormal();} else {window()->showMaximized();}
}void TitleBar::onButtonClicked()
{QPushButton *button = qobject_cast<QPushButton *>(sender());QWidget *window = this->window();if (button == m_minimizeButton) {window->showMinimized();} else if (button == m_maximizeButton) {if (window->isMaximized()) {window->showNormal();} else {window->showMaximized();}} else if (button == m_closeButton) {window->close();}
}

在主窗口中使用自定义标题栏:

#include "titlebar.h"
#include <QVBoxLayout>int main(int argc, char *argv[])
{QApplication app(argc, argv);QWidget window;window.setWindowFlags(Qt::FramelessWindowHint); // 设置无边框TitleBar *titleBar = new TitleBar(&window);titleBar->setWindowTitle("My Application");titleBar->setWindowIcon(QIcon(":/icons/app.ico"));QWidget *centralWidget = new QWidget;// 添加你的主界面组件...QVBoxLayout *layout = new QVBoxLayout(&window);layout->addWidget(titleBar);layout->addWidget(centralWidget);window.show();return app.exec();
}

以上代码实现了一个基本的自定义标题栏,包括标题文字、最小化/最大化/关闭按钮、窗口拖动等功能。您可以根据需求对代码进行修改和扩展,比如添加更多自定义按钮、集成QSS样式等。


结语

通过本文的实战演练,我们成功实现了一个基本的自定义标题栏。当然,这只是一个起点,你可以根据需求进一步扩展和优化,比如添加透明度调节、自定义按钮等。


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

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

相关文章

Open CASCADE学习|迭代NCollection_Sequence<gp_Pnt>

目录 1、NCollection_Sequence 2、NCollection_Sequence 3、迭代NCollection_Sequence 3.1使用传统for循环 3.2使用C11范围for循环 3.3 使用迭代器 3.4使用STL算法 3.5转换为其他容器类型 NCollection_Sequence是Open CASCADE Technology (OCCT) 中的一个模板类&#x…

石子合并(区间dp)-java

石子合并问题是经典的区间dp问题&#xff0c;我们需要枚举中间端点k的情况从而来推出dp数组的值。 文章目录 前言 一、石子合并问题 二、算法思路 1.问题思路 2.状态递推公式 二、代码如下 代码如下&#xff08;示例&#xff09;&#xff1a; 2.读入数据 3.代码运行结果如下&am…

JS生成二维码.jquery.qrcode.min.js

jquery.qrcode.min.js下载地址 https://cdn.staticfile.org/jquery.qrcode/1.0/jquery.qrcode.min.js 1. 生成二维码到img标签 <div style"display:none;" id"qrcodeHide"><img id "qrcode"/>var qrcodeHide jQuery(#qrcodeHide).…

防火墙对于网络攻击都有哪些防御措施?

现如今随着网络技术的快速发展&#xff0c;给人们的生活带来了很多的便利&#xff0c;网络技术也被广泛地应用在各个领域和行业当中&#xff0c;但是在这个过程中也会面临各种网络安全的威胁&#xff0c;给所涉及的企业造成了很大的影响&#xff0c;所以防火墙这一技术&#xf…

yolov9直接调用zed相机实现三维测距(python)

yolov9直接调用zed相机实现三维测距&#xff08;python&#xff09; 1. 相关配置2. 相关代码2.1 相机设置2.2 测距模块2.2 实验结果 相关链接 此项目直接调用zed相机实现三维测距&#xff0c;无需标定&#xff0c;相关内容如下&#xff1a; 1. yolov4直接调用zed相机实现三维测…

LPRNet车牌识别模型训练及CCPD数据集预处理

LPRNet车牌识别模型训练及CCPD数据集预处理 1 LPRNet车牌识别模型训练 1.1 源码:LPRNet_Pytorch-master 源码官网:GitHub - sirius-ai/LPRNet_Pytorch: Pytorch Implementation For LPRNet, A High Performance And Lightweight License Plate Recognition Framework. 链…

Windows搭建Jellyfin影音服务结合内网穿透实现公网访问本地视频文件

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…

【Linux】vim 编辑器

Linux 系统自带了 gedit 和 vi 编辑器&#xff0c;gedit 是图形化界面的操作&#xff0c;而 vi 由比较难用&#xff0c;所以建议安装 vim 编辑器&#xff0c;vim 是从 vi 发展出来的一个文本编辑器&#xff0c;相当于增强版的 vi &#xff0c;其代码补完、编译及错误跳转等功能…

【Unity】组件组合使用心得(单行可自动拓展Scroll View)

在这之前&#xff0c;一直是在使用Scroll View进行滑动内容设置&#xff0c;但设置的都是不明不白的&#xff0c;而且有的时候设置好了之后也不知道是为什么&#xff0c;总感觉哪里不对劲&#xff0c;而且好也不知道为什么好&#xff0c;可能是长时间在做管理上的内容&#xff…

【LeetCode热题100】189. 轮转数组(数组)

一.题目要求 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 二.题目难度 中等 三.输入样例 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: …

宝塔的nginx保活(守护)自用

自己用的服务器盒子&#xff0c;刷的海思&#xff0c;宝塔可能有点小问题&#xff0c;因为是朋友给的&#xff0c;剩下的问题就自己解决吧。 整体运行还算稳定&#xff0c;因为我只跑跑nginx/php/docker&#xff08;mysql跑不了&#xff09;&#xff0c;性能勉强够用&#xff…

【操作系统】CentOS7入门级安装

下载镜像 CentOS镜像下载Download (centos.org) 我们选择第一个 X86_64 CentOS Mirrors List 版本描述X86_X64带64位的32位扩展版(一般安装这个)ARM64 (aarch64)嵌入式。适用于微端(树莓派、机械臂、机械中控)IBM Power (ppc64le)专用于IBM POWER服务器 选择一个合适的链接 …

【运维】Ubuntu 配置DNS服务器

背景 异常表现 部分域名无法解析&#xff0c;表现为 ping ***.com 提示 ping: ***.com: No address associated with hostname尝试解决方案 采用 sudo vim /etc/resolv.conf编辑的形式&#xff0c;指定DNS解析服务器 原始内容如下&#xff1a; nameserver 127.0.0.53 opti…

【ArcGIS微课1000例】0109:ArcGIS计算归一化水体指数(NDWI)

文章目录 一、加载数据二、归一化水体指数介绍三、归一化水体指数计算四、注意事项一、加载数据 加载配套数据0108.rar(本实验的数据与0108的一致)中的Landsat8的8个单波段数据,如下所示: Landsat8波段信息对照表如下表所示: 接下来学习在ArcGIS平台上,基于Landsat8数据…

【论文精读】 GPT,GPT-2,GPT-3:大力出奇迹

系列文章目录 【论文精读】Transformer&#xff1a;Attention Is All You Need 【论文精读】BERT&#xff1a;Pre-training of Deep Bidirectional Transformers for Language Understanding 文章目录 系列文章目录一、前言二、GPT&#xff08;一&#xff09;文章概览&#xf…

20231911 马星 2023-2024-2 《网络攻防实践》实践报五告

1.实践内容 1.1 防火墙配置 任务要求:配置Linux操作系统平台上的iptables,或者Windows操作系统平台上的个人防火墙&#xff0c;完成如下功能&#xff0c;并进行测试: ①过滤ICMP数据包&#xff0c;使得主机不接收Ping包; ②只允许特定IP地址(如局域网中的Linux攻击机192.168.…

Linux 内核同步

一、基本介绍 1、基本概念 Linux 内核同步是指控制多个进程按照一定的规则或顺序访问某些系统资源的机制&#xff0c;下面是几个关键概念 1、临界区和竞争条件 a.临界区&#xff1a;访问和操作共享数据的代码段 b.竞争条件&#xff1a;多个执行线程在一个临界区同时执行 2、死…

并发编程——8.阶段小结

并发编程到目前为止一共发了7篇文章了&#xff0c;下面就并发的内容简单的来做一个阶段性的小结。 在开始&#xff0c;我们通过一个很简单的例子&#xff08;单线程的&#xff09;&#xff0c;讲了Java运行时内存&#xff0c;这部分内容很重要&#xff0c;对于以后理解并发有很…

Composer安装与配置:简化PHP依赖管理的利器(包括加速镜像设置)

在现代的PHP开发中&#xff0c;我们经常会使用许多第三方库和工具来构建强大的应用程序。然而&#xff0c;手动管理这些依赖项可能会变得复杂和耗时。为了解决这个问题&#xff0c;Composer应运而生。Composer是一个PHP的依赖管理工具&#xff0c;它可以帮助我们轻松地安装、更…

微服务和K8S

微服务和Kubernetes&#xff08;通常简称为K8s&#xff09;都是现代软件开发和部署中常用的概念和工具。它们有着各自独特的特点和作用&#xff1a; 1. **微服务**&#xff1a; - **定义**&#xff1a;微服务是一种架构设计风格&#xff0c;将应用程序拆分为一组小型、独立…