Qt自定义标题栏

一、创建项目

最终项目文件结构如下

 

 “iconfont.tff”的使用方式见如下博客,用于更改图标颜色
Qt更改图标颜色_怎么追摩羯座的博客-CSDN博客

二、MyTitleBar.pro

#-------------------------------------------------
#
# Project created by QtCreator 2023-08-28T09:46:06
#
#-------------------------------------------------QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = MyTitleBar
TEMPLATE = app# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0CONFIG += c++11SOURCES += \main.cpp \mainwindow.cpp \titlebar.cppHEADERS += \mainwindow.h \titlebar.hFORMS += \mainwindow.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetRESOURCES += \file.qrc

二、创建自定义标题类TitleBar

titlebar.h代码如下

/*** @brief TitleBar 自定义标题栏*/#ifndef TITLEBAR_H
#define TITLEBAR_H#include <QWidget>
class QLabel;
class QPushButton;class TitleBar : public QWidget
{Q_OBJECT
public:explicit TitleBar(QWidget *parent = nullptr);~TitleBar();void setColor(QString backgroundColor, QString fontColor, QString selectedFontColor);  //设置颜色
protected://界面拖动void mousePressEvent(QMouseEvent* event);  //鼠标按下void mouseMoveEvent(QMouseEvent* event);  //鼠标移动void mouseReleaseEvent(QMouseEvent* event);  //鼠标抬起void mouseDoubleClickEvent(QMouseEvent* event);  //双击标题栏进行界面的最大化/还原bool eventFilter(QObject *obj, QEvent *event);  //事件过滤器private slots:void onClicked();  //进行最小化、最大化/还原、关闭操作void updateMaximize();  //最大化/还原private:QLabel* m_iconLabel;  //显示图标QLabel* m_titleLabel;  //显示标题QPushButton* m_minimizeButton;  //最小化按键QPushButton* m_maximizeButton;   //最大化/还原按键QPushButton* m_closeButton;   //关闭按键QPoint m_mousePosition;  //鼠标按下时的位置bool m_isMousePressed;  //鼠标是否摁下QString m_backgroundColor; //背景色QString m_fontColor; //字体色QString m_selectedFontColor; //被选中的字体色
};#endif // TITLEBAR_H

titlebar.cpp代码如下

#include "titlebar.h"
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QEvent>
#include <QMouseEvent>
#include <QFontDatabase>
#include <QApplication>TitleBar::TitleBar(QWidget *parent): QWidget(parent)
{setFixedHeight(30);//控件初始化m_iconLabel = new QLabel(this);m_titleLabel = new QLabel(this);m_minimizeButton = new QPushButton(this);m_maximizeButton = new QPushButton(this);m_closeButton = new QPushButton(this);//图片自适应控件大小m_iconLabel->setFixedSize(20, 20);m_iconLabel->setScaledContents(true);//设置控件在布局(layout)里面的大小变化的属性m_titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);//设置控件的最小大小和最大大小m_minimizeButton->setFixedSize(30, 25);m_maximizeButton->setFixedSize(30, 25);m_closeButton->setFixedSize(30, 25);//设置控件唯一标识符m_titleLabel->setObjectName("whiteLabel");m_minimizeButton->setObjectName("minimizeButton");m_maximizeButton->setObjectName("maximizeButton");m_closeButton->setObjectName("closeButton");//设置图标int fontId = QFontDatabase::addApplicationFont(":/font/iconfont.ttf");QString fontName = QFontDatabase::applicationFontFamilies(fontId).at(0);QFont iconFont = QFont(fontName);iconFont.setPixelSize(17);m_minimizeButton->setFont(iconFont);m_minimizeButton->setText(QChar(0xe61b));m_minimizeButton->setToolTip(tr("最小化"));m_minimizeButton->installEventFilter(this);m_maximizeButton->setFont(iconFont);m_maximizeButton->setText(QChar(0xe692));m_maximizeButton->setToolTip(tr("向下还原"));m_maximizeButton->installEventFilter(this);m_closeButton->setFont(iconFont);m_closeButton->setText(QChar(0xe723));m_closeButton->setToolTip(tr("关闭"));m_closeButton->installEventFilter(this);//控件布局QHBoxLayout *pLayout = new QHBoxLayout(this);pLayout->addWidget(m_iconLabel);pLayout->addSpacing(5);pLayout->addWidget(m_titleLabel);pLayout->addWidget(m_minimizeButton);pLayout->addWidget(m_maximizeButton);pLayout->addWidget(m_closeButton);pLayout->setSpacing(0);pLayout->setContentsMargins(5, 0, 5, 0);setLayout(pLayout);//信号槽绑定connect(m_minimizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));connect(m_maximizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));connect(m_closeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));
}TitleBar::~TitleBar()
{}/*** @brief MainWindow::mousePressEvent 鼠标双击:界面最大化或还原* @param event 鼠标事件*/
void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{Q_UNUSED(event);emit m_maximizeButton->clicked();
}/*** @brief MainWindow::mousePressEvent 鼠标按下:准备移动* @param event 鼠标事件*/
void TitleBar::mousePressEvent(QMouseEvent *event)
{m_mousePosition = event->pos();m_isMousePressed = true;
}/*** @brief MainWindow::mousePressEvent 鼠标移动* @param event 鼠标事件*/
void TitleBar::mouseMoveEvent(QMouseEvent *event)
{if (m_isMousePressed == true ){QWidget *pWindow = this->window();if(pWindow->isMaximized()) //界面最大时,先还原再移动{pWindow->showNormal();//防止鼠标指针在界面之外m_mousePosition = QPoint(200, 10);pWindow->move(event->globalPos().x() - 200, event->globalPos().y());}else{QPoint movePot = event->globalPos() - m_mousePosition;pWindow->move(movePot);}}
}/*** @brief MainWindow::mousePressEvent 鼠标抬起:移动结束* @param event 鼠标事件*/
void TitleBar::mouseReleaseEvent(QMouseEvent *event)
{Q_UNUSED(event);m_isMousePressed = false;
}/*** @brief TitleBar::eventFilter 事件过滤器* @param obj 过滤对象* @param event 事件* @return*/
bool TitleBar::eventFilter(QObject *obj, QEvent *event)
{switch(event->type()){case QEvent::WindowTitleChange:  //更改标题显示内容{QWidget *pWidget = qobject_cast<QWidget *>(obj);if(pWidget){m_titleLabel->setText(pWidget->windowTitle());}}break;case QEvent::WindowIconChange:  //更改图标{QWidget *pWidget = qobject_cast<QWidget *>(obj);if(pWidget){QIcon icon = pWidget->windowIcon();m_iconLabel->setPixmap(icon.pixmap(m_iconLabel->size()));}}break;case QEvent::WindowStateChange:case QEvent::Resize:updateMaximize();  //最大化/还原break;case QEvent::Enter:  //鼠标悬停在控件上,控件变色{if(obj == m_minimizeButton){m_minimizeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_selectedFontColor));}else if(obj == m_closeButton){m_closeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_selectedFontColor));}else if(obj == m_maximizeButton){m_maximizeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_selectedFontColor));}}break;case QEvent::Leave:  //鼠标离开控件,颜色恢复{if(obj == m_minimizeButton){m_minimizeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_fontColor));}else if(obj == m_closeButton){m_closeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_fontColor));}else if(obj == m_maximizeButton){m_maximizeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_fontColor));}}break;default:break;}return QWidget::eventFilter(obj, event);
}/*** @brief TitleBar::onClicked 进行最小化、最大化/还原、关闭操作*/
void TitleBar::onClicked()
{QPushButton *pButton = qobject_cast<QPushButton *>(sender());QWidget *pWindow = this->window();if (pWindow->isTopLevel()){if(pButton == m_minimizeButton)  //最小化{pWindow->showMinimized();}else if (pButton == m_maximizeButton)  //最大化、还原{pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized();}else if (pButton == m_closeButton)  //关闭{pWindow->close();}}
}/*** @brief TitleBar::updateMaximize 最大化/还原时,更改图标样式*/
void TitleBar::updateMaximize()
{QWidget *pWindow = this->window();if(pWindow->isTopLevel()){bool bMaximize = pWindow->isMaximized();if(bMaximize){m_maximizeButton->setToolTip(tr("向下还原"));m_maximizeButton->setProperty("maximizeProperty", "向下还原");m_maximizeButton->setText(QChar(0xe692));}else{m_maximizeButton->setProperty("maximizeProperty", "最大化");m_maximizeButton->setToolTip(tr("最大化"));m_maximizeButton->setText(QChar(0xe65d));}m_maximizeButton->setStyle(QApplication::style());}
}/*** @brief TitleBar::setColor 更改颜色* @param backgroundColor  背景色* @param fontColor 控件颜色/字体颜色* @param selectedFontColor 鼠标悬停在控件上时的颜色*/
void TitleBar::setColor(QString backgroundColor, QString fontColor, QString selectedFontColor)
{m_backgroundColor = backgroundColor;m_fontColor = fontColor;m_selectedFontColor = selectedFontColor;//按键背景透明,图标颜色为m_fontColorm_minimizeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_fontColor));m_maximizeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_fontColor));m_closeButton->setStyleSheet(QString("QPushButton{background-color:rgba(0,0,0,0);color:%1}").arg(m_fontColor));m_titleLabel->setStyleSheet(QString("QLabel{color:%1}").arg(m_fontColor));
}

三、使用

mainwindow.h代码如下

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "titlebar.h"namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();protected:void resizeEvent(QResizeEvent *event);private:Ui::MainWindow *ui;TitleBar* m_titleBar;  //自定义标题栏
};#endif // MAINWINDOW_H

 mainwindow.cpp代码如下

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_titleBar = new TitleBar(this);m_titleBar->resize(this->width(), 30);m_titleBar->move(0, 0);installEventFilter(m_titleBar);setWindowTitle("Custom Window");  //设置标题内容setWindowIcon(QIcon(":/font/capricorn.png"));  //设置图标//第一个是去掉原边框及标题栏,第二个是保留最小化及还原功能,主要是为了还原,最小化下面实现了this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);ui->menuBar->setVisible(false);  //隐藏菜单栏ui->mainToolBar->setVisible(false);  //隐藏工具栏//ui->statusBar->setVisible(false);  //隐藏状态栏this->showMaximized();  //最大化显示QString backgroundColor = "black"; //背景色QString fontColor = "white"; //字体色QString selectedFontColor = "red"; //被选中的字体色//渐变背景this->setStyleSheet(QString("QMainWindow#MainWindow{background-color:qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 %1, stop:1 %2);}").arg(backgroundColor).arg(fontColor));//设置标题栏颜色m_titleBar->setColor(backgroundColor, fontColor, selectedFontColor);
}MainWindow::~MainWindow()
{delete ui;
}/*** @brief MainWindow::resizeEvent  当界面大小改变时更改标题栏大小* @param event*/
void MainWindow::resizeEvent(QResizeEvent *event)
{Q_UNUSED(event);m_titleBar->resize(this->width(), 30);  //更改标题栏大小
}

四、运行测试

可以显示标题内容和图标

双击标题栏,可以放大缩小,放大/还原图标样式会更改

左键按下标题栏,可以移动界面;当最大化时,界面会先还原再移动

鼠标停放在按键上,按键会变颜色

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

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

相关文章

如何为你的公司选择正确的AIGC解决方案?

如何为你的公司选择正确的AIGC解决方案&#xff1f; 摘要引言词汇解释&#xff08;详细版本&#xff09;详细介绍1. 确定需求2. 考虑技术能力3. 评估可行性4. 比较不同供应商 代码快及其注释注意事项知识总结 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&…

Linux centos7 bash编程(break和continue)

在学习shell知识时&#xff0c;简单编程要从格式入手。 首先学习好单行注释和多行注释。 先学习简单整数的打印输出&#xff0c;主要学习echo命令&#xff0c;学习选项-e -n的使用。 下面的练习是常用的两个分支跳转程序&#xff1a;break和continue。 #!/bin/bash # 这是单…

贪心算法总结篇

文章转自代码随想录 贪心算法总结篇 我刚刚开始讲解贪心系列的时候就说了&#xff0c;贪心系列并不打算严格的从简单到困难这么个顺序来讲解。 因为贪心的简单题可能往往过于简单甚至感觉不到贪心&#xff0c;如果我连续几天讲解简单的贪心&#xff0c;估计录友们一定会不耐…

matlab使用教程(29)—微分方程实例

此示例说明如何使用 MATLAB 构造几种不同类型的微分方程并求解。MATLAB 提供了多种数值算法来求解各种微分方程&#xff1a; 1.初始值问题 vanderpoldemo 是用于定义 van der Pol 方程的函数 type vanderpoldemo function dydt vanderpoldemo(t,y,Mu) %VANDERPOLDEMO Defin…

如何在不重新安装的情况下将操作系统迁移到新硬盘?

通常情况下&#xff0c;当你的硬盘损坏或文件过多时&#xff0c;电脑会变得缓慢且卡顿。这时&#xff0c;你可能会被建议更换为一块更好的新硬盘。 ​ 在比较HDD和SSD之后&#xff0c;许多用户更愿意选择SSD作为他们的新硬盘&#xff0c;因为SSD比HDD更稳定且运行更安…

双核和双路服务器的区别

服务器术语里&#xff0c;大家经常会听到1U、2U&#xff0c;单路、双路&#xff0c;机架式、塔式及刀片式等常用名词。其中&#xff0c;机架式、塔式及刀片式是 指服务器的外形&#xff0c;U是指服务器的高度&#xff0c;路是指服务器的处理器数量。 部分朋友会问&#xff0c;我…

Android 设置app深色、浅色、跟随系统

Android深色模式适配 我们需要再用户设置时候&#xff0c;记录下来&#xff0c;用户的设置&#xff0c;等app再次启动时候&#xff0c;获取之前设置&#xff0c;重新设置 public static void setThemeMode() {int themeModeType SpUtils.getThemeModeType();if (themeModeTyp…

环境安装:rpm安装jdk上线项目

Tomcat安装 解析域名 购买域名并配置 安装Docker yum 卸载以前装过的docker

Seaborn数据可视化(四)

目录 1.绘制箱线图 2.绘制小提琴图 3.绘制多面板图 4.绘制等高线图 5.绘制热力图 1.绘制箱线图 import seaborn as sns import matplotlib.pyplot as plt # 加载示例数据&#xff08;例如&#xff0c;使用seaborn自带的数据集&#xff09; tips sns.load_dataset("t…

算法通关村第十七关——柠檬水找零

贪心&#xff0c;顾名思义&#xff0c;就是挑价值最大的 如果直接挑价值最大的&#xff0c;这样不一定能够达到最优解&#xff0c;因为最终价值多少还要取决于背包容量。 贪心算法解决0-1背包问题的基本思路是&#xff1a;按照物品的单位价值&#xff08;即价值与重量的比值&…

上海市青少年算法2023年7月月赛(丙组)

T1先行后列 题目描述 从 1 开始的 nm 个整数按照先行后列的规律排列如下: 给定 n 与 m,再给定一个数字 c,请输出 c 所在的行数与列数。 输入格式 第一行:两个整数表示 n 与 m 第二行:一个整数表示 c 输出格式 两个整数:表示 c 所在的行数与列数。 数据范围 1≤n,m≤10000…

[SpringBoot3]远程访问@HttpExchange

六、远程访问HttpExchange[SpringBoot3] 远程访问是开发的常用技术&#xff0c;一个应用能够访问其他应用的功能。SpringBoot提供了多种远程访问的技术。基于HTTP协议的远程访问是最广泛的。SpringBoot中定义接口提供HTTP服务。生成的代理对象实现此接口&#xff0c;代理对象实…

MIMIC-IV数据提取教程

一、获取MIMIC-IV数据库 MIMIC-IV数据库需要申请权限&#xff0c;具体怎么申请我之前的博客发的有:MIMIC数据库申请流程 以最新的MIMIC-IV 2.2版本为例&#xff0c;首先打开页面拖动到最底端&#xff1a;https://physionet.org/content/mimiciv/2.2/ 直接下载解压下来&#x…

linux下安装Mycat

1 官网下载mycat 官方网站&#xff1a; 上海云业网络科技有限公司http://www.mycat.org.cn/ github地址&#xff1a; MyCATApache GitHubMyCATApache has 34 repositories available. Follow their code on GitHub.https://github.com/MyCATApache 2 Mycat安装 1 把MyCat…

菜鸟教程《Python 3 教程》笔记(13):迭代器与生成器

菜鸟教程《Python 3 教程》笔记&#xff08;13&#xff09; 13 迭代器与生成器13.1 迭代器13.1.1 创建一个迭代器13.1.2 StopIteration 13.2 生成器13.3 yield 使用浅析13.3.1 通过 iterable 对象来迭代13.3.2 使用 isgeneratorfunction 判断13.3.3 类的定义和类的实例13.3.4 r…

基于材料生成算法优化的BP神经网络(预测应用) - 附代码

基于材料生成算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于材料生成算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.材料生成优化BP神经网络2.1 BP神经网络参数设置2.2 材料生成算法应用 4.测试结果&#xff1a;5…

时序预测 | MATLAB实现基于QPSO-BiGRU、PSO-BiGRU、BiGRU时间序列预测

时序预测 | MATLAB实现基于QPSO-BiGRU、PSO-BiGRU、BiGRU时间序列预测 目录 时序预测 | MATLAB实现基于QPSO-BiGRU、PSO-BiGRU、BiGRU时间序列预测效果一览基本描述程序设计参考资料 效果一览 基本描述 1.时序预测 | MATLAB实现基于QPSO-BiGRU、PSO-BiGRU、BiGRU时间序列预测&a…

C++--完全背包问题

1.【模板】完全背包_牛客题霸_牛客网 你有一个背包&#xff0c;最多能容纳的体积是V。 现在有n种物品&#xff0c;每种物品有任意多个&#xff0c;第i种物品的体积为vivi​ ,价值为wiwi​。 &#xff08;1&#xff09;求这个背包至多能装多大价值的物品&#xff1f; &#xff0…

机器学习基础12-Pipeline实现自动化流程处理(基于印第安糖尿病Pima 数据集)

有一些标准的流程可以实现对机器学习问题的自动化处理&#xff0c;在 scikitlearn 中通过Pipeline来定义和自动化运行这些流程。本节就将介绍如何通过Pipeline实现自动化流程处理。 如何通过Pipeline来最小化数据缺失。如何构建数据准备和生成模型的Pipeline。如何构建特征选择…

C#调用barTender打印标签示例

使用的电脑需要先安装BarTender 我封装成一个类 using System; using System.Windows.Forms;namespace FT_Tools {public class SysContext{public static BarTender.Application btapp new BarTender.Application();public static BarTender.Format btFormat;public void Q…