【QT入门】 无边框窗口设计综合运用之自定义标题栏带圆角阴影的窗口

往期回顾:

【QT入门】 自定义标题栏界面qss美化+按钮功能实现-CSDN博客

【QT入门】 无边框窗口设计之实现窗口阴影-CSDN博客

【QT入门】 无边框窗口设计之实现圆角窗口-CSDN博客

 【QT入门】 无边框窗口设计综合运用之自定义标题栏带圆角阴影的窗口

一、最终效果

二、知识点分析 

其实就是几个知识点的综合运用:

1、自定义标题栏,双击放大效果

2、带窗口阴影,带窗口圆角

3、无边框窗口,实现拉伸效果 

由于都是讲解过的知识点,就不再过多讲述,我直接简单说一下每个类的功能,具体的类逻辑实现讲解大家可以参考之前的文章即可。

1、无边框窗口,实现边框拉伸类CFrameLessWidgetBase

直接继承这个类用可以了。

【QT入门】 设计实现无边框窗口拉伸的公用类-CSDN博客

2、自定义标题栏实现拉伸拖动效果设计样式和按钮功能实现类CTitleBar 

【QT入门】对无边框窗口自定义标题栏并实现拖动和拉伸效果-CSDN博客

【QT入门】 自定义标题栏界面qss美化+按钮功能实现-CSDN博客

3、底层类和顶层类综合运用实现窗口阴影(窗口圆角放在标题栏类一起设置了) 

【QT入门】 无边框窗口设计之实现圆角窗口-CSDN博客 

三、完整示例代码

1、 MainWidget.h

#pragma once

#include <QtWidgets/QWidget>
#include "CFrameLessWidgetBase.h"
#include "CTopWidget.h"
#include <QVBoxLayout>
#include <QGraphicsDropShadowEffect>

//派生于CFrameLessWidgetBase
class MainWidget : public CFrameLessWidgetBase
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = Q_NULLPTR);

private slots:
    void onClose();
    void onDoMax(bool isMax);

private:
    QVBoxLayout* m_pMainVLay = nullptr;
    CTopWidget* m_pTopWidget = nullptr;
    QGraphicsDropShadowEffect* m_pShadow = nullptr;
};

2、 MainWidget.cpp

#include "MainWidget.h"


MainWidget::MainWidget(QWidget *parent)
    : CFrameLessWidgetBase(parent)
{
    //设置窗体透明
    this->setAttribute(Qt::WA_TranslucentBackground, true);

    m_pMainVLay = new QVBoxLayout(this);
    m_pTopWidget = new CTopWidget(this);
    m_pMainVLay->addWidget(m_pTopWidget);
	
    int shadow_width = 30;
    m_pMainVLay->setContentsMargins(shadow_width, shadow_width, shadow_width, shadow_width);
    setLayout(m_pMainVLay);

    //给顶层widget设置背景颜色,不然看不见,因为底层widget已经透明了
    m_pTopWidget->setStyleSheet("background-color:rgb(255, 254, 253)");
    m_pShadow = new QGraphicsDropShadowEffect(this);

    //设置阴影距离
    m_pShadow->setOffset(0, 0);

    //设置阴影颜色  686868
    m_pShadow->setColor(QColor("#0000FF"));

    //设置阴影区域
    m_pShadow->setBlurRadius(shadow_width - 5);

    //给顶层QWidget设置阴影
    m_pTopWidget->setGraphicsEffect(m_pShadow);

    connect(m_pTopWidget, &CTopWidget::sig_close, this, &MainWidget::onClose);
    connect(m_pTopWidget, &CTopWidget::sig_max, this, &MainWidget::onDoMax);
}

void MainWidget::onClose()
{
    close();
}

void MainWidget::onDoMax(bool isMax)
{
    int shadow_width = 25;
    if (isMax)
    {
        shadow_width = 0;
    }
    else
    {

    }

    m_pMainVLay->setContentsMargins(shadow_width, shadow_width, shadow_width, shadow_width);

    //设置阴影区域
    m_pShadow->setBlurRadius(shadow_width);

    //给顶层QWidget设置阴影
    m_pTopWidget->setGraphicsEffect(m_pShadow);
}

3、CTitleBar.h 

#pragma once

#include <QWidget>
#include "ui_CTitleBar.h"

class CTitleBar : public QWidget
{
	Q_OBJECT

public:
	CTitleBar(QWidget *parent = Q_NULLPTR);
	~CTitleBar();

protected:
	void paintEvent(QPaintEvent* event) override;
	void mousePressEvent(QMouseEvent* event) override;
	void mouseDoubleClickEvent(QMouseEvent* event) override;
	
signals:
	void sig_close();
	void sig_max(bool isMax);

private slots:
	void on_Clicked();

private:
	Ui::CTitleBar ui;
};

4、CTitleBar.cpp

#include "CTitleBar.h"
#include <QMouseEvent>
#include <QStyleOption>
#include <QPushButton>
#include <QPainter>

#include <qt_windows.h>
#pragma comment(lib, "user32.lib")

CTitleBar::CTitleBar(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);

	//禁止父窗口影响子窗口样式
	setAttribute(Qt::WA_StyledBackground);

	//左上,右上圆角10;左下,右下圆角0
	//QWidget整个窗口都生效
	this->setStyleSheet("QWidget{background-color:rgb(54,54,54); \
        border-top-left-radius:10px; \
        border-top-right-radius:10px; \
		border-bottom-left-radius:0px; \
		border-bottom-right-radius:0px;}");

	ui.label_title->setText(u8"我是标题");
	ui.label_title->setStyleSheet("QLabel{font-family: Microsoft YaHei; \
		font-size:18px; \
		color:#BDC8E2;background-color:rgb(54,54,54);}");

	ui.btnSet->setFixedSize(32, 32);
	ui.btnSet->setText("");
	ui.btnSet->setFlat(true);
	ui.btnSet->setStyleSheet("QPushButton{background-image:url(:/titlebar/resource/titlebar/set.svg);border:none}" \
		"QPushButton:hover{" \
		"background-color:rgb(99, 99, 99);" \
		"background-image:url(:/titlebar/resource/titlebar/set_hover.svg);border:none;}");

	ui.btnMin->setFixedSize(32, 32);
	ui.btnMin->setText("");
	ui.btnMin->setFlat(true);
	ui.btnMin->setStyleSheet("QPushButton{background-image:url(:/titlebar/resource/titlebar/min.svg);border:none}" \
		"QPushButton:hover{" \
		"background-color:rgb(99, 99, 99);" \
		"background-image:url(:/titlebar/resource/titlebar/min_hover.svg);border:none;}");

	ui.btnMax->setFixedSize(35, 35);
	ui.btnMax->setFlat(true);
	ui.btnMax->setText("");
	ui.btnMax->setStyleSheet("QPushButton{background-image:url(:/titlebar/resource/titlebar/normal.svg);border:none; \
		background-position:center; \
		background-repeat:no-repeat;}  \
		QPushButton:hover{ \
		background-color:rgb(99, 99, 99); \
		background-image:url(:/titlebar/resource/titlebar/normal_hover.svg);border:none;}");

	ui.btnClose->setFixedSize(32, 32);
	ui.btnClose->setFlat(true);
	ui.btnClose->setText("");
	ui.btnClose->setStyleSheet("QPushButton{background-image:url(:/titlebar/resource/titlebar/close.svg);border:none}" \
		"QPushButton:hover{" \
		"background-color:rgb(99, 99, 99);" \
		"background-image:url(:/titlebar/resource/titlebar/close_hover.svg);border:none;}");

	connect(ui.btnMin, SIGNAL(clicked(bool)), this, SLOT(on_Clicked()));
	connect(ui.btnMax, SIGNAL(clicked(bool)), this, SLOT(on_Clicked()));
	connect(ui.btnClose, SIGNAL(clicked(bool)), this, SLOT(on_Clicked()));
}

CTitleBar::~CTitleBar()
{
}

void CTitleBar::paintEvent(QPaintEvent* event)
{
	//决定样式表是否起作用
	QStyleOption opt;
	opt.init(this);
	QPainter p(this);
	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
	QWidget::paintEvent(event);
}

void CTitleBar::on_Clicked()
{
	QPushButton* pButton = qobject_cast<QPushButton*>(sender());

	QWidget* pWindow = this->window();

	if (pWindow->isTopLevel())
	{
		if (pButton == ui.btnMin)
		{
			pWindow->showMinimized();
		}
		else if (pButton == ui.btnMax)
		{
			if (pWindow->isMaximized())
			{
				pWindow->showNormal();
				ui.btnMax->setStyleSheet("QPushButton{background-image:url(:/titlebar/resource/titlebar/normal.svg);border:none;  \
					background-position:center; \
					background-repeat:no-repeat;}  \
					QPushButton:hover{ \
					background-color:rgb(99, 99, 99); \
					background-image:url(:/titlebar/resource/titlebar/normal_hover.svg);border:none;}");
			
				emit sig_max(false);
			}
			else
			{
				pWindow->showMaximized();
				ui.btnMax->setStyleSheet("QPushButton{background-image:url(:/titlebar/resource/titlebar/max.svg);border:none;  \
					background-position:center; \
					background-repeat:no-repeat;}  \
					QPushButton:hover{ \
					background-color:rgb(99, 99, 99);  \
					background-image:url(:/titlebar/resource/titlebar/max_hover.svg);border:none;}");

				emit sig_max(true);
			}
		}
		else if (pButton == ui.btnClose)
		{
			emit sig_close();
		}
	}
}

void CTitleBar::mousePressEvent(QMouseEvent* event)
{
	if (ReleaseCapture())
	{
		QWidget* pWindow = this->window();
		if (pWindow->isTopLevel())
		{
			SendMessage(HWND(pWindow->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
		}
	}

	event->ignore();
}

void CTitleBar::mouseDoubleClickEvent(QMouseEvent* event)
{
	emit ui.btnMax->clicked();
}

5、CTopWidget.h 

#pragma once
#include <QWidget>

class CTopWidget : public QWidget
{
	Q_OBJECT

public:
	CTopWidget(QWidget* p = nullptr);
	~CTopWidget();

signals:
	void sig_close();
	void sig_max(bool isMax);
};

6、CTopWidget.cpp

#include "CTopWidget.h"
#include "CTitleBar.h"
#include <QVBoxLayout>

CTopWidget::CTopWidget(QWidget* p)
    :QWidget(p)
{
    setAttribute(Qt::WA_StyledBackground);
    this->setStyleSheet("QWidget{background-color:rgb(255, 254, 253);border-radius:10px;}");
    //this->setStyleSheet("QWidget{background-color:rgb(255, 254, 253); \
    //    border-bottom-left-radius:15px; \
    //    border-bottom-right-radius:15px;}");

    QVBoxLayout* pVLay = new QVBoxLayout(this);
    CTitleBar* pTitle = new CTitleBar(this);
    QWidget* pWidget = new QWidget(this);

    //需要指定pWidget最小尺寸,或最大尺寸
    pWidget->setMinimumSize(1200, 800);

    pVLay->addWidget(pTitle);
    pVLay->addWidget(pWidget);
    pVLay->setContentsMargins(0, 0, 0, 0);
    setLayout(pVLay);

    connect(pTitle, &CTitleBar::sig_close, this, &CTopWidget::sig_close);
    connect(pTitle, &CTitleBar::sig_max, this, &CTopWidget::sig_max);
}

CTopWidget::~CTopWidget()
{
}

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构进阶篇 之 【交换排序】(冒泡排序,快速排序递归、非递归实现)

当你觉的自己不行时&#xff0c;你就走到斑马线上&#xff0c;这样你就会成为一个行人 一、交换排序 1.冒泡排序 BubbleSort 1.1 基本思想 1.2 实现原理 1.3 代码实现 1.4 冒泡排序的特性总结 2.快速排序 QuickSort 2.1 基本思想 2.2 递归实现 2.2.1 hoare版 2.2.2 …

开发环境->生产环境

1、数据迁移 不涉及docker # 以数据库用户导出数据 mysqldump -h 192.168.1.168 -P 3307 -u abragent -pabragebb17 abragent > abragent.sql# 以root用户导出数据 mysqldump -h 192.168.1.168 -P 3307 -u root -p8d3Ba1b abragent > abragent.sql 涉及docker …

java自动化学习-IntelliJ IDEA新建项目

1、新建项目 2、新建类&#xff0c;右键”src” > “new” >”Java Class” 3、重命名类名

【史上最细教程】项目本地切换Nexus私服步骤

文章目录 1.上传所有jar/pom到私服仓库方式1&#xff1a;Nexus手动上传方式2&#xff1a;mvn deploy命令上传 2.替换项目中所有pom.xml上传下载地址为私服仓库3.替换本地maven setting.xml配置文件4.下载上传验证操作下载jar出现的问题mvn deploy上传jarmvn deploy上传执行脚本…

R语言实现蒙特卡洛模拟算法

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

java 数据结构 Map和Set

目录 搜索树 操作-查找 操作-插入 操作-删除&#xff08;难点&#xff09; Map Map 的常用方法 Set 哈希表 哈希函数 哈希冲突 冲突-避免-负载因子调节&#xff08;重点掌握&#xff09; 冲突-解决 冲突-解决-开散列/哈希桶(重点掌握) 实现HashBuck类 put方法 …

C++实现 “你被骗了” 自动拦截,反诈神器

“Never Gonna Give You Up” &#xff0c; 已经是历经十五年的名梗了&#xff0c;点开这个视频&#xff0c;就说明 你被骗了。 无论是自己点进了一些奇奇怪怪的链接&#xff0c;还是被自动跳转&#xff0c;你都不希望 展开 0x01 原理&规则 【本程序B站视频链接】快去B站…

layui框架实战案例(26):layui-carousel轮播组件添加多个Echarts图标的效果

在Layui中&#xff0c;使用layui-carousel轮播组件嵌套Echarts图表来实现多个图表的展示。 css层叠样式表 调整轮播图背景色为白色&#xff1b;调整当个Echarts图表显示loading…状态&#xff1b;同一个DIV轮播项目添加多个Echarts的 .layui-carousel {background-color: #f…

【图论】有向无环图中一个节点的所有祖先 - 邻接表(DFS)

文章目录 题目&#xff1a;有向无环图中一个节点的所有祖先题目描述代码与解题思路 题目&#xff1a;有向无环图中一个节点的所有祖先 2192. 有向无环图中一个节点的所有祖先 题目描述 代码与解题思路 func getAncestors(n int, edges [][]int) [][]int {g : make([][]int, …

C#清空窗体的背景图片

目录 一、涉及到的知识点 1.设置窗体的背景图 2.加载窗体背景图 3.清空窗体的背景图 二、 示例 一、涉及到的知识点 1.设置窗体的背景图 详见本文作者的其他文章&#xff1a;C#手动改变自制窗体的大小-CSDN博客 https://wenchm.blog.csdn.net/article/details/137027140…

链路追踪原理

分布式系统为什么需要链路追踪&#xff1f; 随着互联网业务快速扩展&#xff0c;软件架构也日益变得复杂&#xff0c;为了适应海量用户高并发请求&#xff0c;系统中越来越多的组件开始走向分布式化&#xff0c;如单体架构拆分为微服务、服务内缓存变为分布式缓存、服务组件通…

IDEA2023.1.1中文插件

1.启动IDEA 选中Customize 2.选择All settings 3.选中Plugins,再搜索栏里输入Chinese,找到 "Chinese (Simplified) Language"插件&#xff0c;点击 Install 进行安装。 4. 安装完成后&#xff0c;重启IntelliJ IDEA&#xff0c;即可看到界面语言已经变为中文。

HashMap为啥线程不安全?

1. HashMap1.7在多线程并发下扩容时&#xff0c;头插法会出现环。 /*** Rehashes the contents of this map into a new array with a* larger capacity. This method is called automatically when the* number of keys in this map reaches its threshold.** If current cap…

回溯算法|491.递增子序列

力扣题目链接 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {if (path.size() > 1) {result.push_back(path);// 注意这里不要加return&#xff0c;要取树上…

[计算机知识] TCP/IP网络模型、MySQL的结构

TCP/IP网络模型 应用层 给用户提供应用功能&#xff0c;如HTTP, DNS 应用层处于用户态&#xff0c;传输层及以下处于内核态 传输层 给应用层提供网络支持&#xff0c;如TCP, UDP TCP提供稳定、面向连接的网络传输协议 应用层的数据可能会太大&#xff0c;就需要进行拆分…

【GAMES101】Lecture08 09 Shading 3 (Texture Mapping cont.) 纹理映射 续集

目录 0 引言1 如何在三角形内进行插值&#xff1a;重心坐标1.1 为什么要在三角形内插值1.2 重心坐标1.3 使用重心坐标做三角形内颜色插值 2 应用纹理2.1 简单的纹理映射&#xff1a;漫反射2.2 问题&#xff1a;纹理放大&#xff08;采用插值解决&#xff09;2.2 点查询和范围查…

Qt主窗口 之:停靠/悬浮窗口(QDockWidget)

一、QDockWidget概述 QDockWidget 是 Qt 中的一个窗口部件&#xff0c;用于创建可停靠的窗口&#xff0c;通常用于构建多文档接口&#xff08;MDI&#xff09;或可定制的用户界面。QDockWidget 允许用户将窗口停靠在应用程序的主窗口周围&#xff0c;或将其拖动到独立的浮动窗…

STM32

GPIO通用输入输出口 GPIO:8种输入输出模式 浮空输入可读取引脚电平&#xff0c;若引脚悬空&#xff0c;电平不确定上拉输入可读取引脚电平&#xff0c;内部接上拉电阻&#xff0c;悬空时默认为高电平下拉输入可读取引脚电平&#xff0c;内部接下拉电阻&#xff0c;悬空时默认…

视频编辑的瑞士军刀,MoviePy库的详解与应用示例

左手编程&#xff0c;右手年华。大家好&#xff0c;我是一点&#xff0c;关注我&#xff0c;带你走入编程的世界。 公众号&#xff1a;一点sir&#xff0c;关注领取python编程资料 在数字媒体的时代&#xff0c;视频内容的创作和编辑变得越来越重要。无论是社交媒体上的短视频&…

【数据结构】初识数据结构与复杂度总结

前言 C语言这块算是总结完了&#xff0c;那从本篇开始就是步入一个新的大章——数据结构&#xff0c;这篇我们先来认识一下数据结构有关知识&#xff0c;以及复杂度的相关知识 个人主页&#xff1a;小张同学zkf 若有问题 评论区见 感兴趣就关注一下吧 目录 1.什么是数据结构 2.…