彩票走势图

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

翻译|使用教程|编辑:龚雪|2024-10-22 11:35:28.610|阅读 16 次

概述:本文主要介绍如何在Qt应用程序中实现一个半透明的背景,欢迎下载最新版组件体验~

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

相关链接:

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

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

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

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

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

Qt技术交流群:166830288      欢迎一起进群讨论

ShapedClock类定义

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

class ShapedClock : public QWidget
{
Q_OBJECT

public:
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;
};

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

由于包含时钟小部件的窗口将没有标题栏,因此我们提供了()和()的实现,来允许在屏幕上拖动时钟,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"));
}

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

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

void ShapedClock::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
event->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);
}

Qt Widget组件推荐
  • QtitanRibbon - Ribbon UI组件:是一款遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,QtitanRibbon致力于为Windows、Linux和Mac OS X提供功能完整的Ribbon组件。
  • QtitanChart - Qt类图表组件:是一个C ++库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。
  • QtitanDataGrid - Qt网格组件:提供了一套完整的标准 QTableView 函数和传统组件无法实现的独特功能。使您能够将不同来源的各类数据加载到一个快速、灵活且功能强大的可编辑网格中,支持排序、分组、报告、创建带状列、拖放按钮和许多其他方便的功能。
  • QtitanDocking:允许您像 Visual Studio 一样为您的伟大应用程序配备可停靠面板和可停靠工具栏。黑色、白色、蓝色调色板完全支持 Visual Studio 2019 主题!


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:慧都网

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP