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

server/2024/10/24 9:12:48/

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.ppmy.cn/server/134400.html

相关文章

舍伍德业务安全架构(Sherwood Applied Business Security Architecture, SABSA)

舍伍德业务安全架构&#xff08;Sherwood Applied Business Security Architecture, SABSA&#xff09;是一个企业级的安全架构框架&#xff0c;它提供了一个全面的方法来设计和实现信息安全策略。SABSA模型将业务需求与安全控制相结合&#xff0c;确保企业的信息安全措施能够支…

【毕业设计】工具大礼包之『Maven3.6.3安装与配置』

系统版本 电脑系统&#xff1a;Windows 10 一.Maven下载 &#x1f3af; 统一版本 apache-maven-3.6.3&#xff0c;下面两种下载方式2选1即可 1.官网直下 官网下载地址 https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/ 找到apache-maven-3.6.3-bin.zip 云盘…

《YOLO 目标检测》—— YOLO v3 详细介绍

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;还未写完&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xf…

Maven进阶——坐标、依赖、仓库

目录 1.pomxml文件 2. 坐标 2.1 坐标的概念 2.2 坐标的意义 2.3 坐标的含义 2.4 自己项目的坐标 2.5 第三方项目坐标 3. 依赖 3.1 依赖的意义 3.2 依赖的使用 3.3 第三方依赖的查找方法 3.4 依赖范围 3.5 依赖传递和可选依赖 3.5.1 依赖传递 3.5.2 依赖范围对传…

Arduino-ESP32机器人控制器设计练习题汇总

机器人 对抗案例 迷宫案例 练习题 数码管计时器 74HC595等 单选题 ESP32与74HC595之间主要通过哪种通信方式连接&#xff1f; A. I2CB. SPIC. UARTD. 串行移位寄存器&#xff08;答案&#xff09;在Arduino环境中&#xff0c;控制74HC595移位寄存器的库是&#xff1f; A. Wi…

Java:抽象类和接口

一.抽象类 1.抽象类概念和语法 ⨀概念&#xff1a; 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是并不是所有的类都是用来描绘对象的&#xff0c;如果一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类。 ⨀语…

MFC学习系列之简单创建与学习

MFC学习系列之简单创建与学习 前言创建关于创建的问题关于控件使用总结 前言 了解一下 创建 基于VS2013进行MFC的项目搭建。 基于vs2013版本太过老旧&#xff0c;从vs2019版本中更新安装MFC控件。 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 MSB8041 此项目需要 MF…

太速科技-456-FMCJ456-14bit 2通道3/2.6/2GS/s ADC +16bit 2通道12.6GS/s DAC FMC AD/DA子卡

FMCJ456-14bit 2通道3/2.6/2GS/s ADC 16bit 2通道12.6GS/s DAC FMC AD/DA子卡 一、产品简介 FMC456是一款高分辨率、高采样率的ADCDAC FMC子板。它同时支持2路14位3.0/2.6/2.0GS/s的A/D通道输入和2路16位12.6GS/s的D/A通道输出&#xff0c;全功率模拟-3dB输入带宽可达9…