QT: 如何移動和縮放一個無邊框視窗
阿新 • • 發佈:2021-07-16
一個QT視窗如下可以做到無邊框:
Window {
id: window
//Designer 竟然不支援..., 設計模式時要注意
flags: Qt.FramelessWindowHint
width: 500
height: 300
title: "Window Title"
}
不過要注意, 這樣QT Designer不支援, 在設計的時候可以先註釋掉, 最後在開啟.
一旦設定了FramelessWindowHint, 系統就不管你這個視窗的移動和縮放了, 就需要自己來處理了.
那怎麼處理哪, 大概有以下思路
- 增加一個接收拖動事件的元件, 讓它跟著滑鼠移動
- 增加一個縮放錨點, 隨著滑鼠縮放
- 增加視窗四周的滑鼠觸發區域, 可以隨著滑鼠向四個方向縮放 (此文沒包括實現) , 可以參考 https://evileg.com/en/post/280/{:target="_blank"}
我們先來看看如果拖動視窗, 程式碼如下:
/** 頭部操作區域. */ Rectangle { id: titleOpRect x: 0 y: 0 width: parent.width height: 30 property string title : "Hello Board" MouseArea { id: mouseMoveWindowArea //height: 20 anchors.fill: parent acceptedButtons: Qt.LeftButton property point clickPos: "0,0" onPressed: { clickPos = Qt.point(mouse.x, mouse.y) //isMoveWindow = true } onReleased: { //isMoveWindow = false } onPositionChanged: { var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y) //如果mainwindow繼承自QWidget,用setPos window.setX(window.x + delta.x) window.setY(window.y + delta.y) } } Button { id: closeButton width: 25 height: parent.height text: "X" anchors.left: parent.left anchors.leftMargin: 0 anchors.bottom: parent.bottom anchors.bottomMargin: 0 flat: true font.bold: true font.pointSize: 14 onClicked: { window.close() } } Text { id: titleText text: title anchors.bottom: parent.bottom //底部留點空間 bottomPadding: 5 } //end titleText Button { id: newStrikeButton width: 25 height: parent.height text: "+" anchors.right: parent.right anchors.rightMargin: 0 anchors.bottom: parent.bottom anchors.bottomMargin: 0 flat: true font.pointSize: 22 } Frame { width: titleOpRect.width height: 1 anchors.bottom: titleOpRect.bottom Rectangle { height: parent.height width: parent.width color: "blue" } } }
關鍵程式碼在MouseArea的onPressed 和 onPositionChanged 事件上. 比較容易.
我們再來看看如果縮放視窗
這次我們只是在視窗右下角放一個小矩形區域, 來捕獲滑鼠移動事件, 以實現縮放.
/** 尾部操作區域. */ Rectangle { id: footOpRect anchors.bottom: parent.bottom width: parent.width height: 30 //resize區域 MouseArea { id: resize anchors { right: parent.right bottom: parent.bottom } width: 15 height: 15 cursorShape: Qt.SizeFDiagCursor property point clickPos: "1,1" //保持視窗左上角不動 property int oldX property int oldY onPressed: { clickPos = Qt.point(mouse.x, mouse.y) //oldWidth = window.width //oldHeight = window.height oldX = window.x oldY = window.y } onPositionChanged: { var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y) var minWidth = 100; var minHeight = 100; //最小 var newWidth = (window.width + delta.x)<minWidth?minWidth:(window.width + delta.x); //最小 var newHeight = (window.height + delta.y)<minHeight?minHeight:(window.height + delta.y); window.width = newWidth; window.height = newHeight; window.x = oldX window.y = oldY } onReleased: { } Rectangle { id: resizeHint color: "red" anchors.fill: resize } } }
這段程式碼網上很常見,
- 不過這裡判斷了視窗的最小高度和寬度, 不會導致視窗太小看不見
- 滑鼠移動會導致負數, 所以這裡也做了判斷.
- 保持視窗左上角不動, 否則滑鼠跑來跑去有問題.
That's all, Thanks.
本文來自部落格園,作者:飛雲~,轉載請註明原文連結:https://www.cnblogs.com/cnscud/p/15020631.html