「Qt Widget中文示例指南」如何实现半透明背景?

Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。

本文将为大家展示如何制作一个带有半透明背景的圆形窗口。

「Qt Widget中文示例指南」如何实现半透明背景?

将背景设置为半透明的小部件将对所有未绘制的像素透明,并且背景将通过不透明度低于100%绘制的像素发光,没有绘制的像素也不会接收任何鼠标输入,这可用于自定义顶级小部件的形状。在大多数窗口系统中,设置某些窗口标志将导致窗口装饰(标题栏、窗口框架、按钮)被禁用,从而允许创建特殊形状的窗口。在这个示例中,我们使用这个特性来创建一个包含模拟时钟的圆形窗口。

由于这个示例的窗口没有提供File菜单或关闭按钮,因此我们提供了一个带有Exit条目的上下文菜单,以便可以关闭该示例,单击窗口上方的鼠标右键来打开此菜单。

点击获取Qt Widget组件下载

ShapedClock类定义

ShapedClock类基于AnalogClock示例中定义的AnalogClock类,整个类定义如下:

class ShapedClock : public QWidget
{
Q_OBJECTpublic:
ShapedClock(QWidget *parent = nullptr);
QSize sizeHint() const override;protected:
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;private:
QPoint dragPosition;
};

paintEvent()现在半透明背景(时钟面)上绘制模拟时钟,此外我们实现了sizeHint(),这样就不必显示地调整小部件的大小。

由于包含时钟小部件的窗口将没有标题栏,因此我们提供了mouseMoveEvent()和mousePressEvent()的实现,来允许在屏幕上拖动时钟,dragPosition变量使我们能够跟踪用户最后单击小部件的位置。

ShapedClock类实现

ShapedClock构造函数设置一个计时器,并将其连接到小部件的update()槽。此外,我们向小部件添加了一个操作,当右键单击小部件时,该操作将通过上下文菜单自动变为可用。

ShapedClock::ShapedClock(QWidget *parent)
: QWidget(parent, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint)
{
setAttribute(Qt::WA_TranslucentBackground);
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&ShapedClock::update));
timer->start(1000);QAction *quitAction = new QAction(tr("E&xit"), this);
quitAction->setShortcut(tr("Ctrl+Q"));
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
addAction(quitAction);setContextMenuPolicy(Qt::ActionsContextMenu);
setToolTip(tr("Drag the clock with the left mouse button.\n"
"Use the right mouse button to open a context menu."));
setWindowTitle(tr("Shaped Analog Clock"));
}

我们通过设置 Qt::WA_TranslucentBackground 小部件属性来请求透明窗口,通过在窗口管理器上设置Qt::FramelessWindowHint 标志来通知窗口管理器该窗口不使用窗口框架来装饰。因此,我们需要为用户提供一种在屏幕上移动时钟的方法。

鼠标按钮事件被传递给mousePressEvent()处理程序:

void ShapedClock::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
event->accept();
}
}

如果在小部件上按下鼠标左键,我们将以全局(屏幕)坐标记录小部件框架的左上角位置(即使隐藏时)与鼠标单击发生点之间的位移。如果用户按住左键移动鼠标,将使用此位移。由于我们对事件进行了操作,因此通过调用它的accept()函数来接受它。

「Qt Widget中文示例指南」如何实现半透明背景?

如果鼠标移动到小部件上,则调用mouseMoveEvent()处理程序。

void ShapedClock::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
move(event->globalPosition().toPoint() - dragPosition);
event->accept();
}
}

如果在移动鼠标时按住左键,则小部件的左上角将移动到通过从全局坐标中的当前光标位置减去dragPosition给出的位置。如果我们拖动小部件,也接受事件。

paintEvent()函数主要与模拟时钟示例中描述的相同,另外我们使用QPainter::drawEllipse()来绘制一个圆形的钟面,将画笔的不透明度降低到90%,并使用调色板的默认背景色。

void ShapedClock::paintEvent(QPaintEvent *)
{
static const QPoint hourHand[4] = {
QPoint(5, 14),
QPoint(-5, 14),
QPoint(-4, -71),
QPoint(4, -71)
};
static const QPoint minuteHand[4] = {
QPoint(4, 14),
QPoint(-4, 14),
QPoint(-3, -89),
QPoint(3, -89)
};
static const QPoint secondsHand[4] = {
QPoint(1, 14),
QPoint(-1, 14),
QPoint(-1, -89),
QPoint(1, -89)
};const QColor hourColor(palette().color(QPalette::Text));
const QColor minuteColor(palette().color(QPalette::Text));
const QColor secondsColor(palette().color(QPalette::Accent));int side = qMin(width(), height());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2);
painter.scale(side / 200.0, side / 200.0);painter.setPen(Qt::NoPen);
painter.setBrush(palette().window());
painter.setOpacity(0.9);
painter.drawEllipse(QPoint(0, 0), 98, 98);
painter.setOpacity(1.0);QTime time = QTime::currentTime();
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);painter.save();
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 4);
painter.restore();for (int i = 0; i < 12; ++i) {
painter.drawRect(73, -3, 16, 6);
painter.rotate(30.0);
}painter.setBrush(minuteColor);painter.save();
painter.rotate(6.0 * time.minute());
painter.drawConvexPolygon(minuteHand, 4);
painter.restore();painter.setBrush(secondsColor);painter.save();
painter.rotate(6.0 * time.second());
painter.drawConvexPolygon(secondsHand, 4);
painter.drawEllipse(-3, -3, 6, 6);
painter.drawEllipse(-5, -68, 10, 10);
painter.restore();painter.setPen(minuteColor);for (int j = 0; j < 60; ++j) {
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
}

最后为小部件实现sizeHint(),以便在它第一次显示时给出一个合理的默认大小:

QSize ShapedClock::sizeHint() const
{
return QSize(200, 200);
}

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

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

相关文章

android openGL ES详解——缓冲区VBO/VAO/EBO/FBO/离屏渲染

目录 一、缓冲区对象概念 二、分类 三、顶点缓冲区对象VBO 1、概念 2、为什么使用VBO 3、如何使用VBO 生成缓冲区对象 绑定缓冲区对象 输入缓冲区数据 更新缓冲区中的数据 删除缓冲区 4、VBO应用 四、顶点数组对象VAO 1、概念 2、为什么使用VAO 3、如何使用VAO…

jupyter notebook改变默认启动路径

安装好Anaconda 3以后&#xff0c;就可以使用Jupyter notebook了&#xff0c;但是我们打开Jupyter notebook后&#xff0c;发现界面是一个默认的目录&#xff0c;这个目录在哪里&#xff1f;如果想把自己写的程序文件保存在自己新建的一个文件夹里&#xff0c;修改默认目录到自…

实现内网穿透的最佳解决方案(无实名认证,完全免费)

目录 ngrok&#xff08;不是很推荐&#xff0c;服务器在国外&#xff0c;已被gfw k了不能用&#xff09; cpolar&#xff08;推荐&#xff0c;无需实名操作简单、服务器在国内&#xff09; SAKURA FRP&#xff08;我的世界玩家中的呼声很高&#xff0c;但要实名认证&#xf…

虚拟光驱软件 PowerISO v8.7.0 中文激活版

PowerISO 是一款虚拟光驱工具及强大的光盘映像文件制作工具。支持创建、编辑、提取、压缩、加密和转换ISO/BIN图像文件。同时自带DISM工具&#xff0c;支持ESD/ISO/WIM/ESD格式转换&#xff0c;制作镜像文件制作U盘启动&#xff0c;支持ISO/BIN/IMG/DAA/WIM等各种常见文件类型。…

C语言初阶:十.结构体基础

♥感谢您阅读本篇文章&#xff0c;文章内容为个人对所学内容的整理总结&#xff0c;欢迎大佬在评论区指点一二。♥ ♥个人主页&#xff1a;折枝寄北-CSDN博客折枝寄北擅长C语言初阶,等方面的知识,折枝寄北关注python,c,java,qt,c语言领域.https://blog.csdn.net/2303_80170533?…

【遗传算法】基于遗传模拟退火算法的风电功率聚类分析

摘要 本文提出了一种基于遗传模拟退火算法的风电功率聚类分析方法。风电功率受气象条件的影响波动较大&#xff0c;给电网调度带来较大挑战。本文通过遗传算法结合模拟退火算法&#xff0c;对风电功率进行聚类分析&#xff0c;旨在挖掘风电功率数据中的模式&#xff0c;提升风…

单管放大电路的分析(Multisim仿真)

绘制原理图 在工作区加入NPN型晶体管 图 1 NPN晶体管 基极电阻R1为50kΩ&#xff0c;集极电阻R2为5 kΩ&#xff0c;直流电源12V&#xff0c;并将电阻与晶体管连接起来。 图 2直流通路 修改晶体管的BF&#xff08;放大倍数&#xff09;为100和VJC&#xff08;等效电阻&#…

coze案例|标准证件照(下)–工作流+Bot设计

项目背景 和 图像流见 教程coze案例|标准证件照(上)–图像流 三、工作流 1、新建工作流 首页“个人空间-工作流-创建工作流” 输入工作流的名称和描述后&#xff0c;点击确认即可。 2、工作流设计 工作流整体流程如下 主要分为以下几个步骤&#xff1a; 开始节点&#…

使用语音模块的开发智能家居产品(使用雷龙LSYT201B 语音模块)

在这篇博客中&#xff0c;我们将探讨如何使用 LSYT201B 语音模块 进行智能设备的语音交互开发。通过这个模块&#xff0c;我们可以实现智能设备的语音识别和控制功能&#xff0c;为用户带来更为便捷和现代的交互体验。 1. 语音模块介绍 LSYT201B 是一个基于“芯片算法”的语音…

Vue3 学习笔记(五)Vue3 模板语法详解

在 Vue3 的世界里&#xff0c;模板语法是我们构建用户界面的基石。今天&#xff0c;让我们一起深入了解 Vue3 的模板语法&#xff0c;我将用通俗易懂的语言和实用的例子&#xff0c;带你掌握这项必备技能。 1、文本插值&#xff1a;最基础的开始 想在页面上显示数据&#xff1f…

2024 BuildCTF 公开赛|MISC

1.what is this? BuildCTF{S0_TH1S_15_M0R5E_C0DE_!!} 2.一念愚即般若绝&#xff0c;一念智即般若生 解压缩密码&#xff1a;s2j6dg* BuildCTF{D3crypt10n_1s_4_l0ng_r04d} 3.如果再来一次&#xff0c;还会选择我吗&#xff1f; 修复png 密码&#xff1a;8!67adz6&#xff…

【AI绘画】Midjourney进阶:对角线构图详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;什么是构图为什么Midjourney要使用构图 &#x1f4af;对角线构图特点应用场景提示词书写技巧测试 &#x1f4af;小结 &#x1f4af;前言 【AI绘画】Midjourney进阶&a…

【QT】windows 平台 QT6.8 安装

qt-online-installer-windows-x64-4.8.1.exe Index of /qt/archive/online_installers/4.8/登录,第一个字母是大写的 如果忘记了,可以在这里“ https://my.qt.io/## D:\Qt6

LDR6328:助力小家电实现TYPE-C接口快充输入

在小家电市场日益繁荣的今天&#xff0c;消费者对产品的要求越来越高&#xff0c;不仅关注功能性和实用性&#xff0c;更追求便捷和高效的充电体验。传统的充电接口如DC、Micro USB等&#xff0c;已经无法满足现代消费者对快速充电和高效数据传输的需求。为此&#xff0c;许多小…

基于SSM轻型卡车零部件销售系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;配件类型管理&#xff0c;配件信息管理&#xff0c;订单信息管理&#xff0c;检修休息管理&#xff0c;系统管理 用户账号功能包括&#xff1a;系统首页&#xff0c;个人中心&…

SMA-BP时序预测 | Matlab实现SMA-BP黏菌算法优化BP神经网络时间序列预测

SMA-BP时序预测 | Matlab实现SMA-BP黏菌算法优化BP神经网络时间序列预测 目录 SMA-BP时序预测 | Matlab实现SMA-BP黏菌算法优化BP神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现SMA-BP黏菌算法优化BP神经网络时间序列预测&#xff08;完…

【C#】调用本机AI大模型流式返回

【python】AI Navigator的使用及搭建本机大模型_anaconda ai navigator-CSDN博客 【Python】AI Navigator对话流式输出_python ai流式返回-CSDN博客 前两章节我们讲解了使用AI Navigator软件搭建本机大模型&#xff0c;并使用python对大模型api进行调用&#xff0c;使其流式返…

JS面试八股文(一)

&#x1f60a;JS面试八股文&#xff08;一&#xff09; 1.JS由哪三部分组成&#xff1f;2.JS有哪些内置对象&#xff1f;3.操作数组的方法有哪些&#xff1f;4.JS对数据类型的检测方式有哪些&#xff1f;5.说一下闭包&#xff0c;闭包有什么特点&#xff1f;6.前端的内存泄漏怎…

【go】仅设想,能不能通过pure go编写页面。

设想 通过pure-go编写页面, 似乎不太好实现&#xff0c; 就当学习前端html基础了。 完成度 0.5% App.go: package srcimport (d "github.com/go-webtools/wgo/core/document""github.com/go-webtools/wgo/core/react""github.com/go-webtools/wgo/c…

Java避坑案例 - 高并发场景下的分布式缓存策略

文章目录 概述缓存常见问题及解决方案把 Redis 当作数据库常用的数据淘汰策略如何选择合适的驱逐算法 缓存雪崩问题复现解决方案 缓存击穿&#xff08;热点缓存失效&#xff09;问题复现解决方案 缓存穿透问题复现解决方案缓存穿透 vs 缓存击穿 缓存与数据库的一致性先更新缓存…