说,我有一个Flickable
,里面有一个Image
。我需要相应地更新contentWidth
和contentHeight
。虽然可以手动进行适当的计算,但我想知道是否有办法获得Image
(以及任何其他Item
)的边界矩形?
编辑(响应Mitch's suggestion):
乍一看,它看起来很棒。我甚至开始认为我在尝试使用Item.childrenRect
属性组时错过了一些东西......不幸的是,修改了提供的示例以便在子项目周围绘制边界,我再次说服了自己childrenRect
的属性不尊重项目的轮换。见下文:
import QtQuick 2.3
import QtQuick.Controls 1.2
Item {
width: 400
height: 400
Component.onCompleted: addChildItem()
function addChildItem() {
var rect = Qt.createQmlObject("import QtQuick 2.3; Rectangle {}", container);
rect.x = Math.random() * 200;
rect.y = Math.random() * 200;
rect.width = 64 * slider.value;
rect.height = 64 * slider.value;
rect.color = "green";
rect.opacity = 0.5;
rect.rotation = Math.random() * 360;
}
Row {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
Slider {
id: slider
value: 0.5
Text {
text: "Child item size"
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.top
}
}
Button {
text: "Add child item"
onClicked: addChildItem()
}
}
Item {
id: container
x: 50
y: 50
}
Item {
x: container.x
y: container.y
Rectangle {
x: container.childrenRect.x
y: container.childrenRect.y
width: container.childrenRect.width
height: container.childrenRect.height
color: "transparent"
border.color: "black"
}
}
}
答案 0 :(得分:0)
childrenRect
应该考虑到轮换的边界矩形,但是有一个错误:childrenRect doesn't take transformations into account.
原始回答:
使用childrenRect:
import QtQuick 2.3
import QtQuick.Controls 1.2
Item {
width: 400
height: 400
Component.onCompleted: addChildItem()
function addChildItem() {
var rect = Qt.createQmlObject("import QtQuick 2.3; Rectangle {}", container);
rect.x = Math.random() * 100;
rect.y = Math.random() * 100;
rect.width = 64 * slider.value;
rect.height = 64 * slider.value;
rect.color = "green";
rect.opacity = 0.5;
rect.rotation = Math.random() * 360;
}
Row {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
Slider {
id: slider
value: 0.5
Text {
text: "Child item size"
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.top
}
}
Button {
text: "Add child item"
onClicked: addChildItem()
}
}
Item {
id: container
anchors.centerIn: parent
}
Text {
text: "Total rotated bounds"
Rectangle {
id: boundsRect
width: container.childrenRect.width
height: container.childrenRect.height
anchors.top: parent.bottom
color: "transparent"
border.color: "black"
}
}
}
答案 1 :(得分:0)
边界矩形可以通过自定义函数计算。以下是QML代码,它确实做了并说明了这一点。下面的代码仅考虑轮换,但是可以进行调整以考虑翻译和缩放比例。知道单个转换项的边界矩形后,就可以遍历多个项的边界矩形并计算总体边界矩形。
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Window 2.11
Window {
width: 640
height: 480
visible: true
function rotatePoint(point, pivotPoint, degrees) {
var radians = degrees * (Math.PI / 180)
var sinAngle = Math.sin(radians)
var cosAngle = Math.cos(radians)
var pointX = point.x
var pointY = point.y
var pivotPointX = pivotPoint.x
var pivotPointY = pivotPoint.y
pointX -= pivotPointX
pointY -= pivotPointY
var rotatedPointX = (pointX * cosAngle - pointY * sinAngle) + pivotPointX
var rotatedPointY = (pointX * sinAngle + pointY * cosAngle) + pivotPointY
return Qt.point(rotatedPointX, rotatedPointY)
}
function calculateBoundingRect(rect, degrees) {
var x = rect.x
var y = rect.y
var width = rect.width
var height = rect.height
var centerPoint = Qt.point(x + width / 2, y + height / 2)
var topLeftPoint = Qt.point(x, y)
var topRightPoint = Qt.point(x + width, y)
var bottomRightPoint = Qt.point(x + width, y + height)
var bottomLeftPoint = Qt.point(x, y + height)
var rotatedTopLeftPoint = rotatePoint(topLeftPoint, centerPoint, degrees)
var rotatedTopRightPoint = rotatePoint(topRightPoint, centerPoint, degrees)
var rotatedBottomRightPoint = rotatePoint(bottomRightPoint, centerPoint, degrees)
var rotatedBottomLeftPoint = rotatePoint(bottomLeftPoint, centerPoint, degrees)
var rotatedPointsXValues = [rotatedTopLeftPoint.x, rotatedTopRightPoint.x, rotatedBottomRightPoint.x, rotatedBottomLeftPoint.x]
var rotatedPointsYValues = [rotatedTopLeftPoint.y, rotatedTopRightPoint.y, rotatedBottomRightPoint.y, rotatedBottomLeftPoint.y]
var rotatedPointsMinX = Math.min.apply(null, rotatedPointsXValues)
var rotatedPointsMaxX = Math.max.apply(null, rotatedPointsXValues)
var rotatedPointsMinY = Math.min.apply(null, rotatedPointsYValues)
var rotatedPointsMaxY = Math.max.apply(null, rotatedPointsYValues)
var boundingRectTopLeftPoint = Qt.point(rotatedPointsMinX, rotatedPointsMinY)
var boundingRectTopRightPoint = Qt.point(rotatedPointsMaxX, rotatedPointsMinY)
var boundingRectBottomLeftPoint = Qt.point(rotatedPointsMinX, rotatedPointsMaxY)
return Qt.rect(
boundingRectTopLeftPoint.x, boundingRectTopLeftPoint.y,
boundingRectTopRightPoint.x - boundingRectTopLeftPoint.x,
boundingRectBottomLeftPoint.y - boundingRectTopLeftPoint.y)
}
Rectangle {
id: rectangle1
width: 100
height: 200
gradient: Gradient {
GradientStop {
position: 0
color: "#1ce327"
}
GradientStop {
position: 1
color: "#0e65ec"
}
}
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
antialiasing: true
rotation: slider.value
property rect boundingRect: calculateBoundingRect(Qt.rect(x, y, width, height), rotation)
}
Rectangle {
id: rectangle
width: rectangle1.boundingRect.width
height: rectangle1.boundingRect.height
color: "#00000000"
antialiasing: true
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
Slider {
id: slider
antialiasing: true
anchors.right: parent.right
anchors.rightMargin: 10
anchors.left: parent.left
anchors.leftMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
from: -720
to: 720
value: 0
}
}