Qt自定义窗口圆角

2023-11-05

Qt设置圆角

在Qt中一般设置窗口圆角有两种方式,

  • QSS
  • 通过paintEvent自绘窗口
QSS 设置圆角

这种设置圆角的方式相对来说比较灵活,但我们设置基类窗口(最外层窗口)用qss就很不方便,会收到后续qss的影响,另外当圆角设置大小超过高度的1/2时,圆角效果就会消失,所以窗口动态变化时,这个用起来也不方便

border-radius:8px;//四个角
border-top-left-radius:8px; 左上角;
border-top-right-radius:8px; 右上角;
border-bottom-left-radius:8px; 左下角;
border-bottom-right-radius:8px; 右下角;

paintEvent自绘窗口

大家最常见的就是绘制同时绘制四个角

void CustomRadiusWidget::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);
	painter.setBrush(bg_color_);
	painter.setPen(Qt::transparent);
	painter.drawRoundedRect(rect(), radius_, radius_);
}

但这时候,如果我们想实现类似qss中让四角某一个或几个实现圆角,就无法实现了,查了一下也没有找到相关的demo。这里把我实现的思路和大家分享一下
核心的思想就是:绘制出四个圆角,然后在不需要的圆角上添加带棱角的矩形进行覆盖

以左上角为例
在这里插入图片描述
核心代码

void CustomRadiusWidget::paintEvent(QPaintEvent *event)
{
	//美化样式,防止设置的圆角过大(超过高度1/2)
	auto half_height = height() / 2;
	auto radius = radius_ > half_height ? height() / 2 : radius_;
	//auto radius = radius_;
	QPainter painter(this);
	QPainterPath draw_path;
	draw_path.addRoundedRect(rect(), radius, radius);
	draw_path.setFillRule(Qt::WindingFill);
	if (!left_top_) {
		draw_path.addRect(0, 0, width() / 2, height() / 2);
	}
	if (!left_bottom_) {
		draw_path.addRect(0, height() / 2, width() / 2, height() / 2);
	}
	if (!right_top_) {
		draw_path.addRect(width() / 2, 0, width() / 2, height() / 2);
	}
	if (!right_bottom_) {
		draw_path.addRect(width() / 2, height() / 2, width() / 2, height() / 2);
	}
	painter.setRenderHint(QPainter::Antialiasing);
	painter.setPen(Qt::transparent);
	painter.setBrush(bg_color_);
	painter.drawPath(draw_path);
}

QPainterPath 填充规则

  • Qt::OddEventFill(奇偶填充规则)判断一个点是否在形状内, 从该点到形状外的位置画一条水平线,并计算交叉点的数量。 如果交叉点的数量为奇数,则该点位于形状内部。 此模式为默认模式。
  • Qt::WindingFill (非零弯曲规则)判断一个点是否在形状内, 从该点到形状外部的位置绘制一条水平线。 确定每个交点处的线的方向是向上还是向下。 绕组数是通过对每个交叉点的方向求和来确定的。 如果数字不为零,则该点位于形状内部。 这种填充模式在大多数情况下也可以被认为是闭合形状的交集。
    在这里插入图片描述
    通过上述代码,你就能随意控制到底是显示哪个圆角
    完整代码
//===================================.h==========================================//
#pragma once
#include <QWidget>
class CustomRadiusWidget : public QWidget
{
	Q_OBJECT
public:
	CustomRadiusWidget(QWidget *parent=nullptr);
	~CustomRadiusWidget();
	void SetRadius(int radius);
	void SetRadiusEnable(bool left_top, bool left_bottom, bool right_left, bool right_bottom);
protected:
	virtual void paintEvent(QPaintEvent* event)override;
private:
	int radius_ = {0};
	QColor bg_color_ = {106 ,90 ,205};
	bool left_top_=false;
	bool left_bottom_ = false;
	bool right_top_ = false;
	bool right_bottom_ = false;
};
//===================================.cpp==========================================//
#include "CustomRadiusWidget.h"
#include <QPainter>
#include <QPainterPath>
CustomRadiusWidget::CustomRadiusWidget(QWidget *parent) : QWidget(parent){
	setWindowFlag(Qt::FramelessWindowHint);
	setAttribute(Qt::WA_TranslucentBackground, true);
}

CustomRadiusWidget::~CustomRadiusWidget() {}

void CustomRadiusWidget::SetRadius(int radius){
	radius_ = radius;
}

void CustomRadiusWidget::SetRadiusEnable(bool left_top, bool left_bottom, bool right_top, bool right_bottom){
	left_top_ = left_top;
	left_bottom_ = left_bottom;
	right_top_ = right_top;
	right_bottom_ = right_bottom;
}

void CustomRadiusWidget::paintEvent(QPaintEvent *event)
{
	auto half_height = height() / 2;
	auto radius = radius_ > half_height ? height() / 2 : radius_;
	QPainter painter(this);
	QPainterPath draw_path;
	draw_path.addRoundedRect(rect(), radius, radius);
	draw_path.setFillRule(Qt::WindingFill);
	if (!left_top_) {
		draw_path.addRect(0, 0, width() / 2, height() / 2);
	}
	if (!left_bottom_) {
		draw_path.addRect(0, height() / 2, width() / 2, height() / 2);
	}
	if (!right_top_) {
		draw_path.addRect(width() / 2, 0, width() / 2, height() / 2);
	}
	if (!right_bottom_) {
		draw_path.addRect(width() / 2, height() / 2, width() / 2, height() / 2);
	}
	painter.setRenderHint(QPainter::Antialiasing);
	painter.setPen(Qt::transparent);
	painter.setBrush(bg_color_);
	painter.drawPath(draw_path);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt自定义窗口圆角 的相关文章

  • Qt:测量事件处理时间

    我想测量我的应用程序中的哪些事件在主线程中需要很长时间才能执行 阻塞 GUI 或者至少是否有任何事件花费的时间超过 比如说 10 毫秒 显然 我对需要很长时间的任务使用线程和并发 但有时很难在其他线程中放入的内容和可以保留在 GUI 中的内
  • Qt:如何连接到 SQLite?

    我安装了 SQLite3 解压到 c sqlite 创建了一个数据库 c sqlite mzsales 现在我试图在 QTableView 中显示其内容 QSqlDatabase db QSqlDatabase addDatabase QS
  • 将 gnuplot 嵌入现有 QtWidget 中

    我正在用 C 创建一个 伪 实时绘图应用程序 使用 gnuplot 作为绘图后端 我的要求之一是绘图必须位于现有窗口内 而不是有一个单独的绘图窗口 gnuplot 默认为 Gnuplot 有一个选项可以指定 Qt 小部件 ID 这似乎适合我
  • 如何为 Windows 构建静态 Qt 库并将其与 Qt Creator 一起使用

    我已经下载了以下 Qt 源 http download qt nokia com qt source qt everywhere opensource src 4 7 3 zip http download qt nokia com qt
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • 为什么 QGraphicsWidget 的选择边框在 QGraphicsScene 中不可见?

    我已经通过一个小部件添加到图形场景 QGraphicSscene QGraphicsProxyWidget 问题是 当我选择该项目时 它被选中 但选择边框不可见 这是代码 QDial dial new QDial Widget dial g
  • Qt中正确的线程方式

    我的图像加载非常耗时 图像很大 并且在加载时也完成了一些操作 我不想阻止应用程序 GUI 我的想法是在另一个线程中加载图像 发出图像已加载的信号 然后用该图像重绘视图 我的做法 void Window loadImage ImageLoad
  • Qt:删除富文本

    对于明文有QFontMetrics elideText https doc qt io qt 5 qfontmetrics html elidedText https doc qt io qt 5 qfontmetrics html eli
  • QWebSocketServer - 不释放内存

    首先 我在安全 websocket 服务器应用程序上运行 valgrind 并发现了一个问题 在 Qt Memcheck 中我必须检查 外部错误 看到它 一些字节是肯定输了 指着我的main就在我的地方QCoreApplication ex
  • 如何将枚举类传递给 QML?

    我正在学习QML with Qt并在通过时遇到一些麻烦enum class to qml 当我使用信号时int参数 一切正常 代码运行完美 But 麻烦就在这里 如果我使用信号与一些enum class我有参数undefinedqml 信号
  • Qt 图表和数据可视化小部件

    我已经安装了 Qt 5 7 来尝试 Qt 图表和 Qt 数据可视化 但我在 Qt Designer 和 Qt Creator 中都找不到新的小部件 有什么建议我应该做什么才能让新的小部件出现在设计器中 我今天遇到了完全相同的问题 默认情况下
  • Qt 编译器标志顺序

    我的目标是消除某些类型的编译器警告 我发现可以通过在 pro 文件中添加编译器标志来做到这一点 QMAKE CXXFLAGS Wno unused variable Wno reorder 问题是它们被添加在 Qt 构建系统生成的标志之前
  • PyQt 和 QSignalMapper/lambdas - 多个信号,单槽

    我在 PyQt 的菜单上有一个操作列表 每个操作对应我想要显示的每个不同的提要 所以我有一个 Y 将活动源设置为 Y Z 将其设置为 Z 等等 对于网络漫画阅读程序 我的菜单上都有 并且觉得自动化方法可能更好 而不是每次都打字 类似于将其添
  • 如何将flex和bison与Qt项目集成?

    我正在 git 源代码控制下使用 Qt4 制作 GUI 程序 Github页面 https github com vinayak garg dic sim 项目的一小部分需要扫描和解析 所以我想在项目中使用flex和bison 我能想到3种
  • Android 版 Qt 和 BoringSSL

    我正在开发一个基于 Qt 的 Android 应用程序 它使用 QSslSocket 下载数据 由于 Android 从 OpenSSL 转向 BoringSSL 因为依赖 OpenSSL 库的 Marshmallow Qt 程序在 And
  • 如何在Qt3D中优化点云渲染

    我正在尝试使用 Qt3D 显示大型点云 20M pts 我第一次发现这个图书馆https github com MASKOR Qt3DPointcloudRenderer https github com MASKOR Qt3DPointc
  • 如何重写(重新实现)QFileSystemModel 中的成员函数

    我已经为此苦苦挣扎了一段时间 Qt s QFileSystemModel由于图标获取算法非常糟糕 在获取数百个文件时速度非常慢 我想完全禁用图标 它们被提取到QFileSystemModel data方法不是虚拟的 QFileSystemM
  • 无法将 [未定义] 分配给 QColor

    我正在使用 Qt 5 11 构建 运行代码 代码中有QML风格如下 Button style delegate Component id enabledButtonStyle ButtonStyle padding top 0 paddin
  • 运行最新版本时没有“最新”消息?

    我正在尝试使用Sparkle https sparkle project org与 Qt Go 的绑定 https github com therecipe qt app 闪光 m import
  • 在信号/槽处理期间删除 QObject

    我知道从槽处理中删除 QObject 可能会使应用程序崩溃 因为它可能有其他排队的事件 因此 我将使用 obj gt deleteLater 而不是使用 delete obj 据我所知 obj 等待处理所有排队的事件 然后 删除 obj Q

随机推荐

  • yolov3之数据集预处理

    目录 txt标签文件的说明 将jpg与txt文件分开 txt生成xml标签文件 xml标签详解 xml标签生成txt txt标签文件的说明 获取到的数据集是这样的 需要转换为VOC格式 其实就是将txt转换为xml文件 打开txt文件可以看
  • 在线代码编辑器:Monaco Editor

    monaco editor是微软开源的一款web版代码编辑器 它支持智能提示 代码高亮 代码格式化 Monaco Editor是为VS Code提供支持的代码编辑器 运行在浏览器环境中 编辑器提供代码提示 智能建议等功能 供开发人员远程更方
  • 2013年9月10日星期二(DEMO8_6矩阵)

    首先设置了2个矩阵 1 把所有的点存储为1 2矩阵 typedef struct MATRIX1X2 TYP float M 2 MATRIX1X2 MATRIX1X2 PTR M X Y 2把所有变换矩阵采用3 2矩阵 typedef s
  • 带你玩转kubernetes-k8s(第21篇:k8s-深入掌握Pod-初始化容器、Pod滚动升级)

    上节内容的错误 还请大家不要太在意 后面我们会解决的 理解Job的作用 概念就可以了 下面我们进入正题 Init Container 初始化容器 在很多应用场景中 应用在启动之前都需要进行如下初始化操作 等待其他关联组件正确运行 例如数据库
  • Gitbash 无法显示中文

    GitBash gt 右键 gt options gt 左侧text 设置locale zh cn 设置Character set GBK save gt apply GitBash输入 systeminfo看能否正常显示
  • 几种C/C++语言安全检测工具介绍

    转自新浪微博http www vckbase com index php wv 1635 针对C C 语言安全漏洞的分析检测也出现了大量的工具 按照不同的机理主要分为以下几类 如表所示 分析类型 机理 分析工具 备注 静态分析 预处理 Fo
  • ## Hive分区、桶、与倾斜

    Hive的分区 1 在Hive Select 查询中一般会扫描整个表内容 会消耗很多时间做没必要的工作 有时候查询 只需要扫描表中关心的一部分数据 因此建表时引入partition概念 2 分区表指的是在创建表时指定的partition的分
  • 数据库查询最近N天数据

    查询最近7天数据 1 查询最近7天订单金额 用到了虚表和UNION ALL的知识 其中 price是要查询的数据 orders是表名 IFNULL b price 0 是指b price如果值为空 则将空值设置为0 SELECT a cli
  • Java版手写数字(0~9)BP神经网络识别

    MNIST的样本集太无趣 连图片都看不到 也无法用人手进行输入 所以 基于BP神经网络的理论知识 参见数据挖掘黑书212页起 讲得甚好 纯手写了一版带训练和测试的小玩具 Java语言 效果如下 代码已上传github https githu
  • 多项式回归(非线性回归)的python代码实现

    1 概述 在解决回归问题中 很多数据集中输入空间与输出空间并非完全呈线性关系 使用线性回归无法解决此类问题 为了解决存在非线性关系的数据集的回归问题 需要进行多项式回归 但sklearn并未提供多项式回归模型的类 多项式回归使用的还是线性回
  • 字节的对齐方式

    VC对结构的存储的特殊处理确实提高CPU存储变量的速度 但是有时候也带来了一些麻烦 我们也屏蔽掉变量默认的对齐方式 自己可以设定变量的对齐方式 重要规则 1 复杂类型中各个成员按照它们被声明的顺序在内存中顺序存储 第一个成员的地址和整个类型
  • 【k8s】k8s部署网络插件Calico、创建网络策略

    一 简介 01 calico简介 calico官网 flannel实现的是网络通信 calico的特性是在pod之间的隔离 通过BGP路由 但大规模端点的拓扑计算和收敛往往需要一定的时间和计算资源 纯三层的转发 中间没有任何的NAT和ove
  • String、StringBuffer与StringBuilder之间区别

    String StringBuffer StringBuilder String的值是不可变的 这就导致每次对String的操作都会生成新的String对象 不仅效率低下 而且浪费大量优先的内存空间 StringBuffer是可变类 和线程
  • Σ-Δ ADC的高精度数模转化,是如何实现的?

    以前接触过 ADC24位采样芯片 一直对其原理没有搞清楚 最近看到有对其原理讲解的文章 因此收集下来作为参考 我们在了解Delta Sigma ADC原理之前 先明确几个概念 1 量化噪声 下图中 蓝色斜线是连续的模拟信号 阶梯状波形是经过
  • Flask学习笔记_异步CMS(五)

    Flask学习笔记 异步CMS 五 1 环境 1 安装nvm 2 安装node 2 使用vue cli创建项目 3 安装相关插件 4 后台CMS开发 1 页面结构 1 app vue搭建结构 2 element icon组件的使用 3 ic
  • matlab rand randn 每次生成的随机数都一样的解决方案

    文章目录 问题说明 解决方案 例子 生成不重复的随机数 生成重复的随机数 结论 参考文献 问题说明 在Matlab应用中 我们经常需要用到随机数 比如rand randn 等函数 都是生成某一类随机数的函数 对于rand 函数来说 每一次启
  • HDR到底是什么?

    此文章转发自互联网 先感谢论坛好友 xiaoyuer520的耐心讲解及推荐这篇文章给我 我愿意分享给大家一起共同进步 谢谢 大家如果有像我一样的 看到文字多的帖子就看不下去 但又很想知道HDR是什么Dolby Vision和HDR10的区别
  • MySQL入门篇之Xtrabackup备份与恢复

    一 Xtrabackup介绍 MySQL冷备 mysqldump MySQL热拷贝都无法实现对数据库进行增量备份 在实际生产环境中增量备份是非常实用的 如果数据大于50G或100G 存储空间足够的情况下 可以每天进行完整备份 如果每天产生的
  • Vue2.7.14、vuecli@5.0.8 升级 vite@4.4.8

    项目背景 Vue2 7 14 vuecli 5 0 8 element ui 2 15 13 node14 18 3 本项目内部项目 不涉及CDN加速 vite安装 pnpm add vite 4 4 8 D 入口文件index html
  • Qt自定义窗口圆角

    Qt设置圆角 在Qt中一般设置窗口圆角有两种方式 QSS 通过paintEvent自绘窗口 QSS 设置圆角 这种设置圆角的方式相对来说比较灵活 但我们设置基类窗口 最外层窗口 用qss就很不方便 会收到后续qss的影响 另外当圆角设置大小