Qt高级--(2)自定义标题栏

自定义标题栏

功能点

1.标题栏中最外层布局器使用水平布局器。
2.导航按钮、工具按钮和窗口功能按钮都是用水平布局器,边距和间隔可根据实际情况设置。
3.编写 QSS 样式,并将样式设置到窗口控件中。
4.实现最小化、最大化和关闭窗口按钮功能。
5.实现鼠标双击标题栏切换窗口状态,最大化状态时切换至正常状态,正常状态切换至最大化状态。
6.鼠标拖动标题栏可在屏幕中移动窗口。
7.鼠标拖动窗体切换窗口状态,拖动至屏幕顶部切换至最大化状态,拖动离开屏幕顶部切换至正常状态。

在这里插入图片描述

源代码

JTitleBar .h

#ifndef JTITLEBAR_H
#define JTITLEBAR_H#include <QWidget>
#include <QMouseEvent>
#include "jnavibutton.h"namespace Ui {
class JTitleBar;
}class JTitleBar : public QWidget
{Q_OBJECTpublic:explicit JTitleBar(QWidget *parent = 0);~JTitleBar();enum WINSTATUS {NORMAL, MAXIMIZED, MINIMIZED};Q_ENUMS(WINSTATUS)void setTitleHeight(int height);public Q_SLOTS:virtual void mousePressEvent(QMouseEvent *event) override;virtual void mouseReleaseEvent(QMouseEvent *event) override;virtual void mouseMoveEvent(QMouseEvent *event) override;virtual void mouseDoubleClickEvent(QMouseEvent *event) override;Q_SIGNALS:void nbtnTab1_clicked();void nbtnTab2_clicked();void nbtnTab3_clicked();void configWin_clicked();void changeSkin_clicked();private:void winStatus_changed();private:Ui::JTitleBar *ui;private:QList<JNaviButton*> m_listNaviButtons;QList<QPushButton*> m_listToolButtons;QList<QPushButton*> m_listWinButtons;int m_titleHeight;QPoint m_startPos;bool m_bLeftButtonPressed;WINSTATUS m_winStatus;bool m_bDragMax;
};#endif // JTITLEBAR_H

.cpp

#include "jtitlebar.h"
#include "ui_jtitlebar.h"
#include <QHBoxLayout>JTitleBar::JTitleBar(QWidget *parent) :QWidget(parent),ui(new Ui::JTitleBar),m_titleHeight(30),m_bLeftButtonPressed(false),m_winStatus(NORMAL),m_bDragMax(false)
{ui->setupUi(this);QHBoxLayout *ui_hLayNaviButton = new QHBoxLayout;ui_hLayNaviButton->addWidget(ui->nbtnTab1);ui_hLayNaviButton->addWidget(ui->nbtnTab2);ui_hLayNaviButton->addWidget(ui->nbtnTab3);ui_hLayNaviButton->addStretch();ui_hLayNaviButton->setContentsMargins(QMargins(0,0,0,0));ui_hLayNaviButton->setSpacing(0);ui->nbtnTab1->setChecked(true);ui->nbtnTab1->setText(QStringLiteral("Tab1"));ui->nbtnTab2->setText(QStringLiteral("Tab2"));ui->nbtnTab3->setText(QStringLiteral("Tab3"));connect(ui->nbtnTab1, &JNaviButton::clicked, [=](){ emit nbtnTab1_clicked(); });connect(ui->nbtnTab2, &JNaviButton::clicked, [=](){ emit nbtnTab2_clicked(); });connect(ui->nbtnTab3, &JNaviButton::clicked, [=](){ emit nbtnTab3_clicked(); });m_listNaviButtons << ui->nbtnTab1 << ui->nbtnTab2 << ui->nbtnTab3;ui->nbtnTab1->setNormalIcon(QPixmap(":/icon/icon/tab1.png"));ui->nbtnTab1->setHoverIcon(QPixmap(":/icon/icon/tab1-hover.png"));ui->nbtnTab1->setCheckedIcon(QPixmap(":/icon/icon/tab1-hover.png"));ui->nbtnTab2->setNormalIcon(QPixmap(":/icon/icon/tab2.png"));ui->nbtnTab2->setHoverIcon(QPixmap(":/icon/icon/tab2-hover.png"));ui->nbtnTab2->setCheckedIcon(QPixmap(":/icon/icon/tab2-hover.png"));ui->nbtnTab3->setNormalIcon(QPixmap(":/icon/icon/tab3.png"));ui->nbtnTab3->setHoverIcon(QPixmap(":/icon/icon/tab3-hover.png"));ui->nbtnTab3->setCheckedIcon(QPixmap(":/icon/icon/tab3-hover.png"));for(auto btn : m_listNaviButtons) {btn->setShowIcon(true);// 设置导航按钮显示图标btn->setNormalBgColor(QColor(50, 57, 76, 0));btn->setHoverBgColor(QColor(0, 0, 0, 50));btn->setCheckedBgColor(QColor(0, 0, 0, 100));btn->setNormalTextColor(QColor(210, 210, 215));btn->setHoverTextColor(QColor(255, 255, 255));btn->setCheckedTextColor(QColor(255, 255, 255));btn->setIconSpace(20);// 设置图标左侧边距btn->setPaddingLeft(30);// 设置文字左侧边距}QHBoxLayout *ui_hlayToolButton = new QHBoxLayout;ui_hlayToolButton->addWidget(ui->btnProject);ui_hlayToolButton->addWidget(ui->btnEdit);ui_hlayToolButton->addWidget(ui->btnSetting);ui_hlayToolButton->addWidget(ui->btnAbout);QMargins margin = ui_hlayToolButton->contentsMargins();margin.setRight(margin.right() + 10);ui_hlayToolButton->setContentsMargins(margin);m_listToolButtons << ui->btnProject << ui->btnEdit << ui->btnSetting << ui->btnAbout;QHBoxLayout *ui_hlayWinButton = new QHBoxLayout;ui_hlayWinButton->addWidget(ui->btnSkin);ui_hlayWinButton->addWidget(ui->btnMin);ui_hlayWinButton->addWidget(ui->btnMax);ui_hlayWinButton->addWidget(ui->btnClose);ui_hlayWinButton->setSpacing(0);margin = ui_hlayWinButton->contentsMargins();margin.setLeft(margin.left() + 10);margin.setRight(margin.right() + 10);ui_hlayWinButton->setContentsMargins(margin);connect(ui->btnSetting, &QPushButton::clicked, [=](){ emit configWin_clicked(); });connect(ui->btnSkin, &QPushButton::clicked, [=](){ emit changeSkin_clicked(); });connect(ui->btnMin, &QPushButton::clicked, this, [=](){ parentWidget()->showMinimized(); });connect(ui->btnMax, &QPushButton::clicked, [=](){ winStatus_changed(); });connect(ui->btnClose, &QPushButton::clicked, [=](){ parentWidget()->close(); });m_listWinButtons << ui->btnSkin << ui->btnMin << ui->btnMax << ui->btnClose;QHBoxLayout *ui_hlayWindow = new QHBoxLayout;ui_hlayWindow->addWidget(ui->btnLogo);		// 添加 LOGO 按钮ui_hlayWindow->addLayout(ui_hLayNaviButton);// 添加导航按钮所在布局器ui_hlayWindow->addStretch();				// 添加一个弹簧ui_hlayWindow->addLayout(ui_hlayToolButton);// 添加工具按钮所在布局器ui_hlayWindow->addWidget(ui->frameLine);	// 添加竖线ui_hlayWindow->addLayout(ui_hlayWinButton);// 添加窗口功能按钮所在布局器ui->btnLogo->setMinimumWidth(180);			// 为 LOGO 按钮设置最小宽度ui->frameLine->setFixedSize(1, 20);			// 将竖线的尺寸设为固定值ui_hlayWindow->setContentsMargins(QMargins(0,0,0,0));ui_hlayWindow->setSpacing(0);setLayout(ui_hlayWindow);setAttribute(Qt::WA_StyledBackground, true);/*QString style = "QWidget#JTitleBar{background: qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 #313947,stop:1 #34375E);}""QPushButton{border: none;}""QPushButton#btnLogo{color:white;}""QPushButton#btnProject{image: url(:/icon/icon/project.png); color:white;}""QPushButton#btnProject:hover{image: url(:/icon/icon/project-hover.png);}""QPushButton#btnEdit{image: url(:/icon/icon/analysis.png); color:white;}""QPushButton#btnEdit:hover{image: url(:/icon/icon/analysis-hover.png);}""QPushButton#btnSetting{image: url(:/icon/icon/setting.png); color:white;}""QPushButton#btnSetting:hover{image: url(:/icon/icon/setting-hover.png);}""QPushButton#btnAbout{image: url(:/icon/icon/about.png);}""QPushButton#btnAbout:hover{image: url(:/icon/icon/about-hover.png);}""QPushButton#btnMin{image: url(:/icon/icon/min.png);}""QPushButton#btnMin:hover{image: url(:/icon/icon/min-hover.png);""background-color: red;}""QPushButton#btnMax{image: url(:/icon/icon/max.png);}""QPushButton#btnMax:hover{image: url(:/icon/icon/max-hover.png);""background-color: red;}""QPushButton#btnClose{image: url(:/icon/icon/close.png);}""QPushButton#btnClose:hover{image: url(:/icon/icon/close-hover.png);""background-color: red;}""QFrame#frameLine{background-color: black;}";setStyleSheet(style);
*/
}JTitleBar::~JTitleBar()
{delete ui;
}void JTitleBar::setTitleHeight(int height)
{if(m_titleHeight != height) {m_titleHeight = height;setFixedHeight(m_titleHeight);ui->btnLogo->setFixedHeight(m_titleHeight);for(auto btn : m_listNaviButtons) {btn->setFixedHeight(m_titleHeight);
//            btn->setFixedWidth(m_titleHeight * 3);btn->setTextAlign(JNaviButton::TextAlign_Center);}}
}void JTitleBar::winStatus_changed()
{// 判断是鼠标左键if(NORMAL == m_winStatus) {// 当前处于正常状态则切换至最大化状态parentWidget()->setWindowState(Qt::WindowMaximized);m_winStatus = MAXIMIZED;return;}if(MAXIMIZED == m_winStatus){// 当前处于最大化状态则切换至正常状态parentWidget()->setWindowState(Qt::WindowNoState);m_winStatus = NORMAL;return;}
}void JTitleBar::mousePressEvent(QMouseEvent *event)
{if(event->button() == Qt::LeftButton) {m_startPos = event->pos();m_bLeftButtonPressed = true;}
}void JTitleBar::mouseReleaseEvent(QMouseEvent *event)
{if(event->button() == Qt::LeftButton) {m_bDragMax = false;m_bLeftButtonPressed = false;}
}void JTitleBar::mouseMoveEvent(QMouseEvent *event)
{if(m_bLeftButtonPressed) {if(m_bDragMax) {return;}if(MAXIMIZED == m_winStatus){// 当前处于最大化状态时切换至正常状态parentWidget()->setWindowState(Qt::WindowNoState);m_winStatus = NORMAL;
//            QPoint p = event->pos() - m_startPos;
//            parentWidget()->move(parentWidget()->x() + p.x(), parentWidget()->y() + p.y());}else {if(event->globalY() <= 2) {// 判断距离屏幕顶部,距离小于 2 时切换至最大化状态parentWidget()->setWindowState(Qt::WindowMaximized);m_winStatus = MAXIMIZED;m_bDragMax = true;return;}else {// 正常移动窗口QPoint p = event->pos() - m_startPos;parentWidget()->move(parentWidget()->x() + p.x(), parentWidget()->y() + p.y());}}}
}void JTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{if(event->button() == Qt::LeftButton) {winStatus_changed();}
}

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

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

相关文章

springboot整合vue2实现简单的新增删除,整合ECharts实现图表渲染

先看效果图&#xff1a; 1.后端接口 // 查询所有商品信息 // CrossOrigin(origins "*")RequestMapping("/list1")ResponseBodypublic List<Goodsinfo> list1(){List<Goodsinfo> list goodsService.list();return list;}// 删除 // …

你绝对需要的Facebook养号攻略,教你如何养成耐用号

Facebook 可谓是大家的“老熟人”了&#xff0c;作为全球热门的社交媒体平台&#xff0c;Facebook 一直以来都是社媒营销、跨境电商的重要阵地&#xff0c;但是很多小伙伴们在注册新账号后往往忽略了一个重要的步骤&#xff0c;也是必不可少的一步&#xff0c;那就是养号&#…

【跨境电商独立站新手入门手册】

一直想要更新一个独立站的系列合集&#xff0c;用小白也看得懂的方式阐述怎么从0到1搭建并运营一个独立站&#xff0c;并且后续我也会录制成视频。 今天&#xff0c;它来了。 这是《跨境电商独立站新手入门手册》系列的第一篇。 你是否有过这样的经历&#xff1a;当你在网上浏…

vue中使用iconfont图标

1. 选择一个图标加入购物车 2、点击右上角购物车图标。点击下载代码&#xff0c;并添加至项目。 3、将下载好的代码文件放入项目中的assets目录的styles下 iconfont.css直接放在styles下 在styles目录下新建目录iconfont&#xff0c;将iconfont.ttf、iconfont.woff、iconfont…

python自动化测试selenium核心技术3种等待方式详解

这篇文章主要为大家介绍了python自动化测试selenium的核心技术三种等待方式示例详解&#xff0c;有需要的朋友可以借鉴参考下&#xff0c;希望能够有所帮助&#xff0c;祝大家多多进步早日升职加薪 UI自动化测试过程中&#xff0c;可能会出现因测试环境不稳定、网络慢等情况&a…

安防监控系统EasyCVR平台调用hls地址生成流的时间过长,该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台可拓展性强、…

[工业自动化-13]:西门子S7-15xxx编程 - 分布式从站 - 硬件配置

目录 前言&#xff1a; 一、通过博图软件完成对ET200 SP分布式从站的硬件配置 二、从站组态配置的常见问题与解决 三、分布式从站与CPU的profiNet连接 3.1 概述 3.2 配置主站与从站的profinet连接 四、Profinet和普通以太网区别 4.1 概述 4.2 协议栈 五、主站与从站连…

【开源】基于JAVA的生活废品回收系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨在鼓…

在 SQL 中,当复合主键成为外键时应该如何被其它表引用

文章目录 当研究一个问题慢慢深入时&#xff0c;一个看起来简单的问题也暗藏玄机。在 SQL 中&#xff0c;主键成为外键这是一个很平常的问题&#xff0c;乍一看没啥值得注意的。但如果这个主键是一种复合主键&#xff0c;而另一个表又引用这个键作为它的复合主键&#xff0c;问…

区域入侵AI算法如何应用在工地场景,保卫工地施工安全?

在工地、厂区等施工场所&#xff0c;安全保障是必不可少的&#xff0c;特别是在人工智能技术日益成熟的今天&#xff0c;如何利用旭帆科技AI智能视频中的区域入侵算法助力智慧工地、保障工地安全呢&#xff1f; 1、建筑物周界安全 TSINGSEE青犀区域入侵算法可以用于监控建筑物…

韩国黄金代理商主动出击时机

受中东局势影响&#xff0c;十月底国际价格一度重新站上2000美元大关&#xff0c;韩国的黄格也随之出现上涨&#xff0c;当地投资者对黄金投资的热情再次升温。在韩国首尔市钟路附近的金店一条街&#xff0c;聚集了大大小小上百家金店&#xff0c;即使是在平日的中午&#xff0…