我在QML ApplicationWindow中有一个应该填充的GridView 与一些项目。
我用JS功能" placeItems"放置我的项目。 但问题是,当调用ApplicationWindow的Component.onCreated信号时,GridView尚未布局。 例如,GridView在ApplicationWindow的Component.onCreated中的x坐标等于-425。 如果我稍后再调用相同的函数 - 一切正常并且GridView 有正确的坐标(= 75)。
我来回检查Qt参考,并且找不到可能有用的其他信号(例如onLayouted或onLayoutComplete)。 问题是何时调用" placeItems"所以ApplicationWindow中的GridView 已经有正确的坐标?
UPDATE1: 要观察不良行为,请在应用程序启动后单击File-> Start。它会将物品放在正确的位置。
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.1
ApplicationWindow {
id: mainWindow
width:1000
height: 900
color : "white"
visible: true
flags: Qt.Window
function max (a,b) { return a>b ? a : b; }
function min (a,b) { return a<b ? a : b; }
property int sizeMin: width < height ? width : height
property int dimField: sizeMin - 50
property int dimCellSpacing: 3
property int dimCell: (dimField / 5 ) - 1 - dimCellSpacing
GridView {
id: field
anchors.centerIn: parent
model: 20
width: dimField
height: dimField
cellWidth: dimCell
cellHeight: dimCell
delegate: cell
property var items: []
function centerCell(column,row) {
return {x: field.x + (column + 0.5) * cellWidth,
y: field.y + (row + 0.5) * cellHeight}
}
function placeItem(name, col, row) {
var c = centerCell(col,row)
items[name].centerX = c.x
items[name].centerY = c.y
}
function placeItems() {
placeItem ("a", 3, 3)
//placeItem ("b", 4, 4)
}
}
Component.onCompleted: field.placeItems()
Component {
id: cell
Rectangle {
id: rectCell
width: dimCell
height: dimCell
color: "lightgray"
border.width: 3
border.color: "brown"
}
}
Rectangle
{
id: rectItemA
property int dimItem: 100
property int centerX: 0
property int centerY: 0
property int margin: 5
property var cell: field.items["a"] = this
border.color: "black"
border.width: 3
width: dimItem
height: dimItem
x: centerX - width/2
y: centerY - height/2
color: "red"
opacity: 0.5
}
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("Start")
onTriggered: field.placeItems();
}
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
}
答案 0 :(得分:1)
function placeItem(name, col, row) {
items[name].anchors.horizontalCenter = field.left;
items[name].anchors.verticalCenter = field.top;
items[name].anchors.horizontalCenterOffset = (col + 0.5) * cellWidth;
items[name].anchors.verticalCenterOffset = (row + 0.5) * cellHeight;
}
关键是将元素锚定在网格视图中,然后根据您的计算移动它。
顺便说一句,你知道QML内置了函数Math.min
/ Math.max
吗?
修改强>
或者更好的是,为什么不直接在rectItemA中定义绑定?
答案 1 :(得分:0)
为什么不延迟placeItems
功能,因此它会以微小的延迟运行,以便在运行&#34;静态&#34;组件都已完成。
Timer {
interval: 250 // might want to tune that
repeat: false
onTriggered: placeItems()
}
在一个完美的世界中,Component.onCompleted
将完美地嵌套,根项目将是最后一个要发射的项目。但遗憾的是Qt并不保证订单,事实上当我做了一个快速测试时,父项目在子项目之前发出(或至少响应)onCompleted
。
如果您不想使用计时器污染您的QML文件,您实际上可以实例化一个&#34;帮助对象&#34;从动态JS函数中,将其设置为完成其工作,然后在完成后自行删除。类似于&#34;重复帮手&#34;我在这个答案中概述了:Better way to reparent visual items in QML而是在计时器超时而不是在JS函数中删除它本身,这样就不会给它时间触发。
答案 2 :(得分:0)
另一种不那么具有正确行为的hackish方式(不要使用带有布局的Timer,真的,这是一个坏主意):
您将Rectangle定义为以属于GridView的项目实例为中心的项目。所以,我使用了一些你的方式(在gridview中的r行和c列中获取项目),然后我将Rectangle重新显示为此项目。要使其居中,只需将其锚定到新绑定的父级的中心。
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.1
ApplicationWindow {
id: mainWindow
width:1000
height: 900
color : "white"
visible: true
flags: Qt.Window
property int sizeMin: Math.min(width, height)
property int dimField: sizeMin - 50
property int dimCellSpacing: 3
property int dimCell: (dimField / 5 ) - 1 - dimCellSpacing
GridView {
id: field
anchors.centerIn: parent
model: 20
width: dimField
height: dimField
cellWidth: dimCell
cellHeight: dimCell
delegate: cell
function cellAt(row, col) {
return itemAt(row * (dimCell + dimCellSpacing), col * (dimCell + dimCellSpacing));
}
}
Component {
id: cell
Rectangle {
id: rectCell
width: dimCell
height: dimCell
color: "lightgray"
border.width: 3
border.color: "brown"
}
}
Rectangle
{
id: rectItemA
property int dimItem: 100
property int margin: 5
border.color: "black"
border.width: 3
width: dimItem
height: dimItem
anchors.centerIn: parent
color: "red"
opacity: 0.5
}
Component.onCompleted: {
rectItemA.parent = field.cellAt(3, 3);
}
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
}