如何缩放QML矩形而不缩放其子文本?
问题:缩放父容器时如何避免子文本被缩放?
我编写了一个QML组件,通过PinchArea缩放image_boundary矩形是预期行为,但作为其子项的Text也被缩放了,这不符合需求。我已经给Text显式设置了scale: 1.0和固定的font.pointSize,但文本还是会跟着缩放,想知道原因,以及如何实现“属于可缩放组件但自身不缩放的文本”。
原QML代码
import QtQuick 2 Rectangle { id: page width: 1000; height: 1000 color: "black" Rectangle { id: image_boundary color: "green" width: 200 height: 100 x: (parent.width/2)-(image_boundary.width/2) y: (parent.height/2)-(image_boundary.height/2) onScaleChanged: { console.log("Scale changed:", scale) } PinchArea { anchors.fill: image_boundary property real initialScale: 1.0 property real scale: 1.0 id: pinch_area onPinchStarted: { initialScale = scale } onPinchUpdated: function(pinch) { scale = initialScale * pinch.scale console.log(scale) parent.scale = scale } } Text { text: "mumble mumble" font.pointSize: 10 scale: 1.0 color: "yellow" anchors.left: parent.right } } }
运行用Python代码(基于PySide6)
import sys from pathlib import Path from PySide6.QtQuick import QQuickView from PySide6.QtCore import QUrl from PySide6.QtGui import QGuiApplication if __name__ == '__main__': #Set up the application window app = QGuiApplication(sys.argv) view = QQuickView() view.setResizeMode(QQuickView.SizeRootObjectToView) #Load the QML file qml_file = Path(__file__).parent / "test_qml_file.qml" view.setSource(QUrl.fromLocalFile(qml_file.resolve())) #Show the window if view.status() == QQuickView.Error: sys.exit(-1) view.show() #execute and cleanup app.exec() del view
为什么Text会被缩放?
QML中父项的scale变换是全局继承的,父容器的缩放会直接作用于所有子元素的坐标系。你给Text设置的scale:1.0,是在父容器已经缩放后的空间里保持1倍比例,最终视觉上还是跟着父容器放大/缩小了——相当于父项先把整个坐标系缩放,子项的scale是基于这个缩放后的坐标系计算的,所以无法抵消父项的缩放效果。
解决方法
方案1:将Text移到父容器同级,绑定锚点位置
把Text从image_boundary的子项改成和它同级,直接锚定到目标位置,这样Text完全不受父容器缩放影响:
import QtQuick 2 Rectangle { id: page width: 1000; height: 1000 color: "black" Rectangle { id: image_boundary color: "green" width: 200 height: 100 x: (parent.width/2)-(image_boundary.width/2) y: (parent.height/2)-(image_boundary.height/2) onScaleChanged: { console.log("Scale changed:", scale) } PinchArea { anchors.fill: image_boundary property real initialScale: 1.0 property real scale: 1.0 id: pinch_area onPinchStarted: { initialScale = scale } onPinchUpdated: function(pinch) { scale = initialScale * pinch.scale console.log(scale) parent.scale = scale } } } // 移到同级层级,锚定到image_boundary的右侧 Text { text: "mumble mumble" font.pointSize: 10 color: "yellow" anchors.left: image_boundary.right anchors.verticalCenter: image_boundary.verticalCenter } }
方案2:用中间Item分离缩放层和文本层
如果需要Text保留在原容器层级内,可以在外层套一个Item,只让内部的矩形参与缩放,Text放在外层Item中:
import QtQuick 2 Rectangle { id: page width: 1000; height: 1000 color: "black" Item { id: container width: 200 height: 100 x: (parent.width/2)-(container.width/2) y: (parent.height/2)-(container.height/2) // 仅这个矩形参与缩放 Rectangle { id: image_boundary color: "green" anchors.fill: parent onScaleChanged: { console.log("Scale changed:", scale) } PinchArea { anchors.fill: image_boundary property real initialScale: 1.0 property real scale: 1.0 id: pinch_area onPinchStarted: { initialScale = scale } onPinchUpdated: function(pinch) { scale = initialScale * pinch.scale console.log(scale) parent.scale = scale } } } // Text放在外层Item,不受缩放影响 Text { text: "mumble mumble" font.pointSize: 10 color: "yellow" anchors.left: parent.right anchors.verticalCenter: parent.verticalCenter } } }
内容的提问来源于stack exchange,提问作者Henry Gomersall
相关产品推荐
相关产品推荐

