qml创建Window主要是以下两种做法:
- 使用QQmlApplicationEngine加载qml文件,qml中顶层元素必须为Window或ApplicationWindow;
- 使用QQuickView加载qml文件,qml中顶层元素不能为Window/ApplicationWindow,因为QQuickView继承于QQuickWindow,本身就是一个Window;
实现效果如下图所示:
1. 加载qml代码
// QQmlApplicationEngine
#include <QQmlApplicationEngine>
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
// QQuickView
#include <QQmlContext>
#include <QQuickView>
QQuickView *viwer = new QQuickView();
viwer->setSource(QUrl("qrc:/main.qml"));
viwer->rootContext()->setContextProperty("mainwindow", viwer);
viwer->show();
2. 设置无边框
// QQuickView
QQuickView viewer = new QQuickViewer();
viewer->setFlags(Qt::FramelessWindowHint);
// QQmlApplicationEngine
ApplicationWindow {
// 其余代码省略
flags: Qt.FramelessWindowHint
}
3. 设置模态
// QQuickView
QQuickView *viewer = new QQuickView();
viewer->setFlags(Qt::FramelessWindowHint);
viewer->setModality(Qt::ApplicationModal);
// QQmlApplicationEngine
ApplicationWindow {
// 其余代码省略
flags: Qt.FramelessWindowHint
modality: Qt.ApplicationModal
}
4. 设置边缘阴影
在设置无边框属性时,系统会使窗口会失去标题栏和边缘阴影效果,在QWidget中亦是如此,因此需要手动加上边缘阴影效果及标题栏中的关闭按钮等。在QML中,阴影的实现主要是DropShadow。
import QtGraphicalEffects 1.12 // for DropShadow
ApplicationWindow {
id: mainWindow
visible: true
width: 1050
height: 689
color: "#00000000"
// 如果不加上Qt.Window,则程序不会依附在任务栏
flags: Qt.FramelessWindowHint | Qt.Window
modality: Qt.ApplicationModal
// 其余省略代码...
Rectangle { // 用以放置窗口中的所有内容
id: mainRec
width: parent.width-20
height: parent.height-20
anchors.centerIn: parent
// 其余省略代码...
}
// 左边缘及上边缘阴影
DropShadow {
anchors.fill: mainRec
horizontalOffset: -5
verticalOffset: -5
radius: 12.0
samples: 25
color: "#20000000"
spread: 0.0
source: mainRec
}
// 右边缘及下边缘阴影
DropShadow {
anchors.fill: mainRec
horizontalOffset: 5
verticalOffset: 5
radius: 12.0
samples: 25
color: "#20000000"
spread: 0.0
source: mainRec
}
}
5. 关闭按钮
import QtQuick.Controls 2.0
Button {
id: closeBtn
width: 25
height: 25
anchors.right: parent.right
anchors.rightMargin: 5
anchors.top: parent.top
anchors.topMargin: 5
palette {
button: "transparent"
}
Image {
width: 25
height: 25
fillMode: Image.PreserveAspectFit
source: "qrc:/close.png"
}
MouseArea {
anchors.fill: parent
onClicked: {
mainWindow.close()
}
}
}
以QQmlApplicationEngine为例,总的实现代码如下:
main.qml
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
import QtGraphicalEffects 1.12
ApplicationWindow {
id: mainWindow
visible: true
width: 1050
height: 689
color: "#00000000"
flags: Qt.FramelessWindowHint
modality: Qt.ApplicationModal
MouseArea {
x: 10
y: 10
height: 50
width: parent.width-20
acceptedButtons: Qt.LeftButton
property point clickPos: "0,0"
onPressed: {
clickPos = Qt.point(mouse.x,mouse.y)
}
onPositionChanged: {
var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)
mainWindow.setX(mainWindow.x+delta.x)
mainWindow.setY(mainWindow.y+delta.y)
}
}
Rectangle {
id: mainRec
width: parent.width-20
height: parent.height-20
anchors.centerIn: parent
Text {
id: name
anchors.top: parent.top
anchors.topMargin: 100
anchors.left: parent.left
anchors.leftMargin: 100
text: testData.getCurrentDateTime()
}
Button {
id: closeBtn
width: 25
height: 25
anchors.right: parent.right
anchors.rightMargin: 5
anchors.top: parent.top
anchors.topMargin: 5
palette {
button: "transparent"
}
Image {
width: 25
height: 25
fillMode: Image.PreserveAspectFit
source: "qrc:/close.png"
}
MouseArea {
anchors.fill: parent
onClicked: {
mainWindow.close()
}
}
}
}
// 左边缘及上边缘阴影
DropShadow {
anchors.fill: mainRec
horizontalOffset: -5
verticalOffset: -5
radius: 12.0
samples: 25
color: "#20000000"
spread: 0.0
source: mainRec
}
// 右边缘及下边缘阴影
DropShadow {
anchors.fill: mainRec
horizontalOffset: 5
verticalOffset: 5
radius: 12.0
samples: 25
color: "#20000000"
spread: 0.0
source: mainRec
}
}
QtTest.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QQmlContext>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QGuiApplication>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 点击界面上的按钮打开此qml窗口
connect(ui->pushButton, &QPushButton::clicked, this, [=]()
{
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
});
}
Widget::~Widget()
{
delete ui;
}