Qt6.7.2下,qml中Window组件全屏加载WebEngineView实现圆角
环境:Qt6.7.2 ,windows11 ,CMake项目
前提:Windows {
………
flags: Qt.Window | Qt.FramelessWindowHint //无边框
WebEngineView {
id: webView
anchors.centerIn: parent
width: parent.width
height: parent.height
……
}
}
如果windows不是无边框的,按照网上的资料或demo基本也可以实现
但怪就怪在windows是无边框的,同时,WebEngineView是fill的,如果不是fill的,留有margin ,那直接用Rectangle的圆角,在包上WebEngineView就可以了,
网上一查都说用Rectangle的clip就可以,实践之下,其实是错的,webEngineView的渲染和graphics的不一样,clip根本不生效
废话不多说,
正确的方案是什么呢?
是给QuickWindow设置mask ---及setmask ,,具体代码如下核心代码如下:
Window {
flags: Qt.Window | Qt.FramelessWindowHint
color: "transparent"
TFramelessHelper {
id: framelessHelper
titleBarHeight: 62 //38
}
……
Component.onCompleted: {
framelessHelper.applyRoundedMask(windowRadius)
}
}
void TFramelessHelper::applyRoundedMask(int radius)
{
Q_D(TFramelessHelper);
if (d->window) {
int width = d->window->width();
int height = d->window->height();
d->window->setColor(Qt::transparent);
QBitmap bitmap(width, height);
bitmap.fill(Qt::color0);
QPainter painter(&bitmap);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(Qt::color1);
painter.drawRoundedRect(0, 0, width, height, radius, radius);
d->window->setMask(bitmap);
}
}
或者main.cpp中:
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *rootObject = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(rootObject);
if (window) {
// 设置窗口背景透明,这样圆角外的区域就会透明
window->setColor(Qt::transparent);
// 创建一个圆角矩形的遮罩
QBitmap bitmap(800, 600); // 窗口大小,需要根据实际窗口大小调整
bitmap.fill(Qt::color0); // 初始化为全透明
QPainter painter(&bitmap);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(Qt::color1);
painter.drawRoundedRect(0, 0, 800, 600, 15, 15); // 圆角半径15
window->setMask(bitmap);
}
这个及可以实现想要的效果了,但有个问题
qml中,尤其是Qt6.7中,窗口阴影一般是通过
layer.effect: MultiEffect {
shadowEnabled: true
shadowColor: "#40000000"
shadowBlur: 0.6
shadowVerticalOffset: control.offset
shadowHorizontalOffset: control.offset
}
去实现的,其实是内部模拟出的阴影,
如果用setMask去实现了圆角化,再想要加上阴影,就比较困难了,时间有限,目前我是没想到比较好的解决方案,当然,可以setMask一张带半透明阴影的图片也行。