一,需求

利用QML实现无边框窗体,要求可移动,可缩放。

二,效果

三,实现

//主窗体
import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Window 2.3

import "./widget"

Window {
id: window
visible: true
flags: Qt.FramelessWindowHint|Qt.Window
width: 1024
height: 768
color: "#0F1013"
property int bw: 3

//改变鼠标形状
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: {
const p = Qt.point(mouseX, mouseY)
const b = bw + 10
if (p.x < b && p.y < b) return Qt.SizeFDiagCursor
if (p.x >= width - b && p.y >= height - b) return Qt.SizeFDiagCursor
if (p.x >= width - b && p.y < b) return Qt.SizeBDiagCursor
if (p.x < b && p.y >= height - b) return Qt.SizeBDiagCursor
if (p.x < b || p.x >= width - b) return Qt.SizeHorCursor
if (p.y < b || p.y >= height - b) return Qt.SizeVerCursor
}
acceptedButtons: Qt.NoButton
}

DragHandler {
id: resizeHandler
grabPermissions: TapHandler.TakeOverForbidden
target: null
onActiveChanged: if (active) {
const p = resizeHandler.centroid.position
const b = bw + 10
let e = 0;
if (p.x < b) { e |= Qt.LeftEdge }
if (p.x >= width - b) { e |= Qt.RightEdge }
if (p.y < b) { e |= Qt.TopEdge }
if (p.y >= height - b) { e |= Qt.BottomEdge }
window.startSystemResize(e);
}
}

MyToolBar{
window:window
}
}

//工具栏
import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Window 2.3

ToolBar {
height: 50
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
x:bw
y:bw

property var window: null
//关闭 最大化 最小化按钮
function toggleMaximized(mode) {
if(mode===0){
if (window.visibility === Window.Maximized) {
window.showNormal();
} else {
window.showMaximized();
}
}else if(mode===1){
window.showMinimized()
}else if(mode===2){
window.close()
}else if(mode===4){
return window.visibility
}

}

Rectangle{
id:rectBk
anchors.fill: parent
color: "#1F2025"
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
property point clickPos: "0,0"
onPressed: {
clickPos = Qt.point(mouse.x, mouse.y)
}
onDoubleClicked: {
toggleMaximized(0)
}
onPositionChanged: {
//鼠标偏移量
var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)

window.setX(window.x+delta.x)
window.setY(window.y+delta.y)
}
}
}

Row{
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
spacing: 0
Rectangle{
width: 50
height: 50
color: Qt.rgba(0,0,0,0)
Image {
anchors.centerIn: parent
id: min
source: "qrc:/image/icon/minus.png"
width: 26
height: 26
}
MouseArea{
anchors.fill: parent
hoverEnabled: true
onClicked: {
toggleMaximized(1)
}
onEntered: {
parent.color = "#454B57"
}

onExited: {
parent.color = Qt.rgba(0,0,0,0)
}
}
}

Rectangle{
width: 50
height: 50
color: Qt.rgba(0,0,0,0)
Image {
id: max
source: (toggleMaximized(4) === Window.Maximized)?"qrc:/image/icon/maximize.png":"qrc:/image/icon/maximize2.png"
anchors.centerIn: parent
width: 26
height: 26
}
MouseArea{
anchors.fill: parent
hoverEnabled: true
onClicked: {
console.log("max")
toggleMaximized(0)
}
onEntered: {
parent.color = "#454B57"
}
onExited: {
parent.color = Qt.rgba(0,0,0,0)
}
}
}

Rectangle{
width: 50
height: 50
color: Qt.rgba(0,0,0,0)
Image {
id: close
source: "qrc:/image/icon/close.png"
anchors.centerIn: parent
width: 26
height: 26
}
MouseArea{
anchors.fill: parent
hoverEnabled: true
onClicked: {
toggleMaximized(2)
}
onEntered: {
parent.color = "#454B57"
}

onExited: {
parent.color = Qt.rgba(0,0,0,0)
}
}
}

}

//标题
Text {
id:title
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 20
color: "#FFFFFF"
font.pixelSize: 24
text: qsTr("影像检测仪")
}

Menu {
id:settingMenu
x:setting.x
y:setting.y+setting.height+1
width: 120
Action {
text: qsTr("创建项目")
onTriggered: console.log("创建项目")

}
Action {
text: qsTr("编辑项目")
onTriggered: console.log("编辑项目")
}

delegate: MenuBarItem {
id: settingMenuItem
height: 40
width: 120

contentItem: Text {
text: settingMenuItem.text
font.pixelSize: 16
color: "#ffffff"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}

background: Rectangle {
implicitWidth: 120
implicitHeight: 40
color: Qt.rgba(0,0,0,0)
MouseArea{
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
onClicked: {
settingMenu.close()
settingMenuItem.action.trigger()
}
onEntered: {
parent.color = "#454B57"
}

onExited: {
parent.color = Qt.rgba(0,0,0,0)
}
}
}
}
background: Rectangle {
implicitWidth: 150
implicitHeight: 40
color: "#1F2025"
}
}

//设置
Rectangle{
id:setting
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left:title.right
anchors.leftMargin: 100
color: Qt.rgba(0,0,0,0)
width: 100

Row{
anchors.centerIn: parent
spacing: 2
Text {
color: "#FFFFFF"
font.pixelSize: 20
text: qsTr("设置")
verticalAlignment: Text.AlignVCenter
anchors.verticalCenter: parent.verticalCenter
}
Image {
width: 32
height: 32
anchors.verticalCenter: parent.verticalCenter
source: "qrc:/image/icon/down.png"
}
}
MouseArea{
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
onClicked: {
settingMenu.open()
}
onEntered: {
parent.color = "#454B57"
}

onExited: {
parent.color = Qt.rgba(0,0,0,0)
}
}

}

//关于菜单
Menu {
id:aboutMenu
x:about.x
y:about.y+about.height+1
width: 120
Action {
text: qsTr("关于这个")
onTriggered: console.log("关于这个")
}
Action {
text: qsTr("关于那个")
onTriggered: console.log("关于那个")
}

delegate: MenuBarItem {
id: aboutMenuItem
height: 40
width: 120

contentItem: Text {
text: aboutMenuItem.text
font.pixelSize: 16
color: "#ffffff"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}

background: Rectangle {
implicitWidth: 120
implicitHeight: 40
color: Qt.rgba(0,0,0,0)
MouseArea{
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
onClicked: {
aboutMenu.close()
aboutMenuItem.action.trigger()
}
onEntered: {
parent.color = "#454B57"
}

onExited: {
parent.color = Qt.rgba(0,0,0,0)
}
}

}

}
background: Rectangle {
implicitWidth: 150
implicitHeight: 40
color: "#1F2025"
}
}
//关于
Rectangle{
id:about
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left:setting.right
color: Qt.rgba(0,0,0,0)
width: 100

Row{
anchors.centerIn: parent
spacing: 2
Text {
color: "#FFFFFF"
font.pixelSize: 20
text: qsTr("关于")
verticalAlignment: Text.AlignVCenter
anchors.verticalCenter: parent.verticalCenter
}
Image {
width: 32
height: 32
anchors.verticalCenter: parent.verticalCenter
source: "qrc:/image/icon/down.png"
}
}
MouseArea{
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
onClicked: {
aboutMenu.open()
}
onEntered: {
parent.color = "#454B57"
}

onExited: {
parent.color = Qt.rgba(0,0,0,0)
}
}

}
}