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.hqwc.cn/news/93630.html

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

相关文章

Javase | IO流

目录&#xff1a; 1.输入 (Intput/Read)2.输出 (Output/Write)3.IO4.IO流5.IO流的分类&#xff1a;5.1 分类总述5.2 按照 “流的方向” 进行分类5.3 按照 “读取数据的方式” 进行分类 6.IO包下要重点掌握的流&#xff1a;6.1 文件专属 (流)6.2 转换流 ( 将字节流转换为字符流 …

H.264视频编码推荐的分辨率和码率配置表

Video Encoding Settings for H.264 Excellence 针对H.264编码格式&#xff0c;根据不同分辨率&#xff0c;推荐其对应的码率配置关系如下图所示&#xff1a; 如下为上限&#xff0c;超过这个上限再增加码率基本无太大意义&#xff01;根据业务场景、帧率&#xff0c;建议码率…

小文智能GPT助手介绍

如何使用小文交互的GPT助手&#xff0c;让AI更加智能&#xff0c;适用更多场景&#xff1f; 在小文智能最新推出的4.0版本&#xff0c;有一个新功能&#xff0c;叫做GPT助手。GPT助手&#xff0c;顾名思义&#xff0c;即在小文智能的场景中&#xff0c;接入ChatGPT&#xff0c…

详解vue3中ref和reactive用法和区别

vue3中ref和reactive区别 1、前言2、基本用法2.1 ref2.2 reactive 3、ref和reactive定义数组对比3.1 ref定义数组3.1 reactive定义数组 4、ref 和reactive的区别 1、前言 ref和reactive是Vue3中用来实现数据响应式的API&#xff0c;一般情况下&#xff0c;ref定义基本数据类型…

重磅OpenAI发布ChatGPT企业版本

8月29日凌晨&#xff0c;Open AI官网发布ChatGPT企业版本&#xff01; 企业版简介&#xff1a; ChatGPT企业版提供企业级安全和隐私、无限的高速 GPT-4 访问、用于处理更长输入的更长上下文窗口、高级数据分析功能、自定义选项等等。人工智能可以协助和提升我们工作生活的各个…

python爬虫—requests

一、安装 pip install requests 二、基本使用 1、基本使用 类型 &#xff1a; models.Response r.text : 获取网站源码 r.encoding &#xff1a;访问或定制编码方式 r.url &#xff1a;获取请求的 url r.content &#xff1a;响应的字节类型 r.status_code &#xff1a;响应…

Midjourney学习(三)6个高级应用

使用Remix Mode在原图片的基础上进行二次创作 通过prompt得到大图之后&#xff0c;点击Make Variations按钮&#xff0c;输入Remix Prompt&#xff0c;即可得到意想不到的效果&#xff01; 局部内容重绘 通过局部重绘可以实现对画面内容更加精细化的控制&#xff0c;同样也是需…

three.js(一):认识three.js并创建第一个3D应用

three.js 概述 1-three.js 是什么&#xff1f; three.js是用JavaScript编写的WebGL第三方库;three.js 提供了非常多的3D显示和编辑功能;具体而言&#xff0c;three.js 是一款运行在浏览器中的 3D 引擎&#xff0c;可以用three.js 创建各种三维场景&#xff0c;并对其进行编辑…

动手学深度学习(四)多层感知机

经过了多层感知机后&#xff0c;相当于将原始的特征转化成了新的特征&#xff0c;或者说提炼出更合适的特征&#xff0c;这就是隐藏层的作用。 from&#xff1a;清晰理解多层感知机和反向传播 - 知乎 一、多层感知机的从零开始实现 import torch from torch import nn from d2…

网络基础之重中之重

目录 IP协议 ​编辑 基本概念&#xff1a; 协议头格式&#xff1a; ​编辑 网段划分 DHCP &#xff1a; CIDR&#xff1a; 特殊的IP地址&#xff1a; IP地址的数量限制&#xff1a; 私有IP和公网IP 路由 路由的过程&#xff1a; 数据链路层 认识以太网&#x…

Java 大厂八股文面试专题-设计模式 工厂方法模式、策略模式、责任链模式

面试专题-设计模式 前言 在平时的开发中&#xff0c;涉及到设计模式的有两块内容&#xff0c;第一个是我们平时使用的框架&#xff08;比如spring、mybatis等&#xff09;&#xff0c;第二个是我们自己开发业务使用的设计模式。 面试官一般比较关心的是你在开发过程中&#xff…

Unity编辑器扩展 | 编辑器扩展基础入门

前言 Unity编辑器扩展 | 编辑器扩展基础一、基本概念二、核心知识点 简述三、相关API 总结 前言 当谈到游戏开发工具&#xff0c;Unity编辑器是一个备受赞誉的平台。它为开发者提供了一个强大且灵活的环境&#xff0c;使他们能够创建令人惊叹的游戏和交互式体验。然而&#xf…