首页 > 技术文章 > Quick之QML自定义窗口标题栏

shHome 2020-11-19 14:47 原文

前言
  `在实际的开发中,QML自带的组件基本上不会直接用,因为需要花里胡哨的样式,所以需要我们。`
运行效果

知识点
  • ApplicationWindow
  • Item
  • MouseArea
  • Button
实现思想
// <1> 隐藏原生窗口的系统标题栏
// Qt.Window >> 指定该部件为窗口属性。请注意,如果小部件没有父级,则无法取消设置此标志。
// Qt.FramelessWindowHint >> 设置窗口属性为无边框样式
flags: Qt.Window | Qt.FramelessWindowHint

<2> 自定义窗口标题栏样式
// 直接定义一个 Item 或者其他组件作为窗口的标题栏即可
// 窗口的id为 rootWindow
// 处理窗口 onTitleChanged 信号,同步到自定义标题栏即可
    Rectangle {

        id : rootWindowMenuBar
        width: rootWindow.width
        height: 40

        Text {
            id: rootWindowTitleBarTitleText
            text: rootWindow.title
        }
    }

<3> 自定义窗口标题栏事件
// MouseArea >> 不可见的组件,其功能提供鼠标处理信号
 MouseArea {

     MouseArea {

    anchors.fill: rootWindowTitleBar
    // 只处理鼠标左键
    acceptedButtons: Qt.LeftButton
    // 接收鼠标按下事件
    onPressed: {

        rootWindow.rootWindowTitleMousePos = Qt.point(mouseX,mouseY)
        rootWindow.isMoveWindow = true
    }

    // 鼠标释放,关闭窗口移动flag
    onReleased: {

        if(mouse.button === Qt.LeftButton){

            rootWindow.isMoveWindow = false
        }
    }

    //
    onMouseXChanged: {

        if(rootWindow.isMoveWindow){

            rootWindow.x += mouseX - rootWindow.rootWindowTitleMousePos.x;
        }
    }
    onMouseYChanged: {

        rootWindow.y += mouseY - rootWindow.rootWindowTitleMousePos.y;
    }
}

<4> 自定义窗口标题栏样式

Button {

	id : pushbtnWindowsClose
	width: 30
	height: 30
	anchors.margins: 5
	anchors.right: rootWindowTitleBar.right
	anchors.topMargin: 5
	anchors.verticalCenter: parent.verticalCenter
	text: "X"
}

Button {

	id : pushbtnWindowsMaximize
	width: 30
	height: 30
	anchors.margins: 5
	anchors.verticalCenter: parent.verticalCenter
	anchors.right: pushbtnWindowsClose.left
	text: "口"
}

Button {

	id : pushbtnWindowsMinimize
	width: 30
	height: 30
	anchors.margins: 5
	anchors.verticalCenter: parent.verticalCenter
	anchors.right: pushbtnWindowsMaximize.left
	text: "一"
}
完整QML代码
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5

ApplicationWindow {

    property bool isMoveWindow: false
    property point rootWindowTitleMousePos: Qt.point(x,y)

    id : rootWindow
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    flags: Qt.Window | Qt.FramelessWindowHint

    onTitleChanged: rootWindowTitleBarTitleText.text = title

    Rectangle {

        id : rootWindowTitleBar
        width: rootWindow.width
        height: 40

        border.color: "red"
        color: "black"

        Text {
            id: rootWindowTitleBarTitleText
            text: rootWindow.title
            color: "white"
            anchors.verticalCenter: parent.verticalCenter
        }

        // 为窗口标题栏添加鼠标事件
        MouseArea {

            anchors.fill: rootWindowTitleBar
            // 只处理鼠标左键
            acceptedButtons: Qt.LeftButton
            // 接收鼠标按下事件
            onPressed: {

                rootWindow.rootWindowTitleMousePos = Qt.point(mouseX,mouseY)
                rootWindow.isMoveWindow = true
            }

            // 鼠标释放,关闭窗口移动flag
            onReleased: {

                if(mouse.button === Qt.LeftButton){

                    rootWindow.isMoveWindow = false
                }
            }

            //
            onMouseXChanged: {

                if(rootWindow.isMoveWindow){

                    rootWindow.x += mouseX - rootWindow.rootWindowTitleMousePos.x;
                }
            }
            onMouseYChanged: {

                rootWindow.y += mouseY - rootWindow.rootWindowTitleMousePos.y;
            }
        }

        Button {

            id : pushbtnWindowsClose
            width: 30
            height: 30
            anchors.margins: 5
            anchors.right: rootWindowTitleBar.right
            anchors.topMargin: 5
            anchors.verticalCenter: parent.verticalCenter
            text: "X"
        }

        Button {

            id : pushbtnWindowsMaximize
            width: 30
            height: 30
            anchors.margins: 5
            anchors.verticalCenter: parent.verticalCenter
            anchors.right: pushbtnWindowsClose.left
            text: "口"
        }

        Button {

            id : pushbtnWindowsMinimize
            width: 30
            height: 30
            anchors.margins: 5
            anchors.verticalCenter: parent.verticalCenter
            anchors.right: pushbtnWindowsMaximize.left
            text: "一"
        }
    }

}

推荐阅读