I am creating some Rectangles dynamically with a Text element inside like so:
Rectangle {
id: root
width: 640; height: 480
property var items: []
property int count
function push() {
var temp = Qt.createQmlObject("import QtQuick 2.3; Rectangle {width: 100; height: 30;color: 'yellow'; Text {text: count; anchors.centerIn: parent}}", root, "")
temp.x = Math.floor(Math.random()*200 + 1)
temp.y = Math.floor(Math.random()*200 + 1)
items[count] = temp
count++
}
MouseArea {
anchors.fill: parent
onClicked: push()
}
}
Now, whenever I call the push function by clicking, it creates a new rectangle with present value of count. But the problem is all rectangles created so far change their text to present value of count. I need to create rectangles with present value of count and they should not change their text when count changes afterwords. How can I do this? Thanks!
The Rectangles you are creating have this code :
Text {
text: count
anchors.centerIn: parent
}
Here, there is a binding between the text property and count. So whenever the countchanges, the text will reflect that change.
You need to escape the count in your string definition to actually concatenate the current value of count so that the code for the first item is :
Text {
text: '0'
anchors.centerIn: parent
}
You code shoud then be :
Rectangle {
id: root
width: 640; height: 480
property var items: []
property int count
function push() {
var temp = Qt.createQmlObject("import QtQuick 2.3; Rectangle {width: 100; height: 30;color: 'yellow'; Text {text: '"+count+"'; anchors.centerIn: parent}}", root, "")
temp.x = Math.floor(Math.random()*200 + 1)
temp.y = Math.floor(Math.random()*200 + 1)
items[count] = temp
count++
}
MouseArea {
anchors.fill: parent
onClicked: push()
}
}
Related
I'm coding a widget that can be expanded to its FullRepresentation by being clicked on:
onClicked: {
plasmoid.expanded = !plasmoid.expanded
}
I have a function that updates its contents and puts them into a Gridview. The update function is first called from Component.onCompleted, but then I call it every time the user updates the data. The problem is the data I feed into the expandable FullRepresentation can contain a varying number of elements that I put into the gridview and calculate its AND the FullRepresentation's sizes based on this number.
However, I find I'm only able to specify the Representation's size from the Component.onCompleted block. When I call the update function outside it, it doesn't change the size, no matter whether the size is defined in the item properties like so:
Item
{
id: fullRepresentation
width: no_items > 2 ? 465 : no_items * 155
height: Math.ceil(no_items / 3)* 155
property int no_items
...and I only try to change the no_items property from the UpdateFunction, or just try to run the two equations from it.
Is there any way around this? I've also tried the implicitHeight and implicitWidth properties. I really would like to be able to dynamically adjust the size of the main expandable representation, it feels bad to have to hardcode it and then have a lot of unfilled space.
EDIT:
Here is the requested example:
Root.qml
import org.kde.plasma.plasmoid 2.0
import QtQuick 2.2
Item
{
id: root
width: 185; height: 185
Plasmoid.compactRepresentation: Compact {}
Plasmoid.fullRepresentation: Full {}
Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation
signal addItems()
}
Compact.qml
import QtQuick 2.2
Item
{
Rectangle
{
width: root.width; height: root.height
MouseArea
{
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: if (mouse.button == Qt.RightButton) root.addItems()
else plasmoid.expanded = !plasmoid.expanded
}
}
}
Full.qml
import QtQuick 2.2
Item
{
width: no_items > 2 ? 465 : no_items * 155
height: Math.ceil(no_items / 3)* 155
property int no_items : 0
function redrawGridView()
{
readingListModel.clear()
var i
for (i = 0; i < no_items; i++) readingListModel.append({})
}
function addItems()
{
no_items = 6
width = no_items > 2 ? 465 : no_items * 155
height = Math.ceil(no_items / 3)* 155
redrawGridView()
}
ListModel
{
id: readingListModel
}
GridView
{
id: readingGridView
width: count > 2 ? 465 : count * 155
height: Math.ceil(count/3) * 155
cellWidth: 155; cellHeight: 155
model: readingListModel
delegate: Rectangle
{
width: 150; height: 150;
}
}
Component.onCompleted:
{
root.addItems.connect(addItems)
no_items = 3
redrawGridView()
}
}
Well, I got no answer but I've figured this out myself.
Indeed, this doesn't seem to be possible using the plasmoid.expanded method with the Full Representation, and produces other bugs, as I mentioned in my comment.
But you can dynamically resize a Window item size from anywhere in your code, so this works just fine:
in Compact.qml
Full
{
id: fullRep
}
MouseArea
{
anchors.fill: parent
onClicked:
{
if (!fullRep.visible) fullRep.show()
else fullRep.close()
}
}
start of Full.qml
Window
{
x: 100;y: 100
width: 465;height: 195
color: theme.backgroundColor
flags: Qt.FramelessWindowHint //You can make it frameless like the expandable
//representation is when using the previous method
I'd like to have Flow in which the objects are added from the left to the right, but each row is aligned to the right.
import QtQuick 2.0
import QtQuick.Controls 2.0
Flow {
width: 400
anchors.right: parent.right
spacing: 2
Repeater {
model: ['a', 'b', 'c', 'd', 'e', 'f', 'g']
delegate: Button {
text: modelData
width: (83 * (model.index + 1)) % 100 + 30
}
}
}
I have the Flow aligned to the right, but the rows in it will always start at the Flows left edge. I could set
layoutDirection: Qt.RightToLeft
which would align the rows to the right, but the order of the items would be reversed as well.
If I reverse the model (in this example possible by calling reverse(), with a ListModel I would need a reversing ProxyModel) a would be to the left, but the rows are out of order.
How could I achive something like that?
import QtQuick 2.5
import QtQuick.Controls 2.1
ApplicationWindow {
id: root;
width: 640
height: 480
visible: true
Rectangle {
z: -1
color: "#80000000"
width: flow.width
height: flow.height
anchors.centerIn: flow
}
Flow {
id: flow
width: 400
anchors.right: parent.right
spacing: 2
Repeater {
id: repeater
property real remainingRowSpace: flow.width
property real indexOfFirstItemInLastRow: 0
model: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q']
delegate: Rectangle {
property real buttonWidth: (83 * (model.index + 1)) % 100 + 30
color: "#80000000"
width: buttonWidth
height: childrenRect.height
Button {
x: parent.width - width
text: modelData
width: parent.buttonWidth
}
}
onItemAdded: {
var spacing = parent.spacing
// Check if new row.
if (item.width > remainingRowSpace) {
// Increase width of first item push row right.
itemAt(indexOfFirstItemInLastRow).width += remainingRowSpace
// Reset available space
remainingRowSpace = parent.width
// Store index of item
indexOfFirstItemInLastRow = index
// Don't need to subtract spacing for the first item
spacing = 0
}
remainingRowSpace -= (item.width + spacing)
// Handle when no more rows will be created.
if (index === repeater.count - 1) {
itemAt(indexOfFirstItemInLastRow).width += remainingRowSpace
}
}
}
}
}
It's not a very versatile or dynamic solution, but it works.
This is still a work in progress but might still be usable for some people
Just as the solution of Tony Clifton, it uses a Repeater and it's onItemAdded-method, but uses Qt.binding to keep things more dynamic. It is not superior to Tony Cliftons solution and the choice might depend on the usecase.
Upsides:
Dynamic to changes of the individual Item-width
Dynamic to the width of the ReversedFlow
Downsides:
Fills the bottom row first. First row might not be full (for some usecases this might be better)
Both solutions wont work, when used with a ListModel and a new entry is being insert()ed. Both solutions should work, when the model is completly replaced (e.g with JSArrays and a manual call of modelChanged()).
Both solutions are no Flows in the sense, that you can throw in arbitrary objects as a Repeater takes care of the layout. So the Repeater has to create the Items. I did not get it working with an ObjectModel. Getting rid of the Repeater will be my last concern.
Item {
id: root
visible: false
width: 400
height: (rep.count > 0 ? rep.itemAt(0).y * -1 : 0)
anchors.centerIn: parent
property real spacing: 5
Item {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
Repeater {
id: rep
model: ListModel {
id: bm
ListElement { text: "a" }
ListElement { text: "b" }
ListElement { text: "c" }
ListElement { text: "d" }
ListElement { text: "e" }
ListElement { text: "f" }
ListElement { text: "g" }
ListElement { text: "h" }
ListElement { text: "i" }
}
onItemAdded: {
console.log(index, item, itemAt(index - 1))
item.anchors.right = Qt.binding(
function() {
if (rep.count === index + 1) return parent.right
var neighbor = rep.itemAt(index + 1)
if (neighbor.x - item.width - root.spacing < 0) return parent.right
return rep.itemAt(index + 1).left
}
)
item.anchors.bottom = Qt.binding(
function() {
if (rep.count === index + 1) return parent.bottom
var neighbor = rep.itemAt(index + 1)
if (neighbor.x - item.width - root.spacing < 0)
return neighbor.top
return neighbor.bottom
}
)
item.anchors.rightMargin = Qt.binding(
function() {
return (item.anchors.right === parent.right ? 0 : root.spacing)
}
)
item.anchors.bottomMargin = Qt.binding(
function() {
return (item.anchors.bottom === rep.itemAt(index + 1).top ? root.spacing : 0)
}
)
}
delegate: Button {
text: modelData
property int count: 0
width: (83 * (index + count + 1)) % 100 + 30
onClicked: {
count++
}
}
}
}
Rectangle {
id: debug
anchors.fill: parent
color: 'transparent'
border.color: 'red'
}
}
The idea behind this, is to initialize bindings of the anchors when the objects are added, where I anchor each Item to either the right side or it's successor, if there is enough space.
I also anchor the bottom of the Item to it's successors bottom, if it is next to him, or to it's top, if it starts a new row. If it has no successor, it will be anchored to the bottom of the parent.
The latter fact, makes this strange construct with two enclosing Items necessary. The outer on will really enclose everything, and dynamically grow, but this can't be the one, I anchor the whole chain to, as I anchor to the bottom. If I would change the height depending on the childrenRect.height I would end in a binding loop with strange effects, as the y-values of the Items would not stay constant. Initially it would work, but when the the items move due to size changes, it would break.
I have a qml element and want to show a (own) tooltip element as a new window right above this element. for this i need the absolute screen position to place the new window (AFAIK).
i got as far that the regular approach is to use "mapToItem" to get the relative position, but i cannot get to the "main window" - because the element in question is located within a "Loader" (which in this case is again located in another Loader).
So my question is: Is it possible to access the mainWindow from inside the dynamically loaded component, or is there maybe another easier way to anchor a new (tooltip) window right above an element ?
EDIT
mapToGlobal would probably work too, but i have to use qt 5.6.
i finally got it to work by setting the main window as a context property in c++:
this->qmlEngine->rootContext()->setContextProperty("mainWindow", this->root);
and in qml i can then access the main window position (on screen) and add the relative position the item has to the shown window like that:
tooltipWindow.setX(mainWindow.x +item1.mapToItem(item2,0,0).x )
The Window item has contentItem especially for that
[read-only] contentItem : Item
The invisible root item of the scene.
So you can refer to Window.contentItem as if it was Window:
import QtQuick 2.7
import QtQuick.Window 2.2
Window {
id: mainWindow
visible: true
width: 600
height: 300
Component {
id: testElement
Rectangle {
id: rect
width: 100
height: 100
color: "orange"
border { width: 1; color: "#999" }
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: tooltip.show(true);
onExited: tooltip.show(false);
onPositionChanged: tooltip.setPosition(mapToItem(mainWindow.contentItem,mouse.x, mouse.y));
}
}
}
Item {
x: 40
y: 50
Item {
x: 80
y: 60
Loader {
sourceComponent: testElement
}
}
}
Rectangle {
id: tooltip
visible: false
width: 100
height: 20
color: "lightgreen"
border { width: 1; color: "#999" }
Text {
anchors.centerIn: parent
text: "I'm here"
}
function show(isShow) {
tooltip.visible = isShow;
}
function setPosition(point) {
tooltip.x = point.x - tooltip.width / 2;
tooltip.y = point.y - tooltip.height;
}
}
}
As for me I would reparent tooltip Item to hovered item itself at MouseArea.onEntered and so you can avoid position recalculation etc.:
onEntered: tooltip.show(true, rect);
onExited: tooltip.show(false);
onPositionChanged: tooltip.setPosition(mouse.x, mouse.y);
...
function show(isShow, obj) {
obj = (typeof obj !== 'undefined' ? obj : null);
if(obj !== null) {
tooltip.parent = obj;
}
tooltip.visible = isShow;
}
function setPosition(x, y) {
tooltip.x = x - tooltip.width / 2;
tooltip.y = y - tooltip.height;
}
I've loaded a PNG image into my QML code and enabled dragging on it.
Image {
source: "image.png"
width: 128
height: 128
MouseArea {
anchors.fill: parent
drag.target: parent
}
}
The problem is that the whole image is selectable, even the transparent parts which I need to disable selecting on these areas. I even tried to make the Canvas from the image, but the problem remains.
Canvas {
width: 128
height: 128
Component.onCompleted: loadImage("image.png")
onImageLoaded: requestPaint()
onPaint: {
var ctx = getContext("2d")
var im = ctx.createImageData("image.png")
im.data[3] = 128
ctx.drawImage(im, 0, 0)
}
MouseArea {
anchors.fill: parent
drag.target: parent
}
}
Here is the image which the only red part should be selectable:
Any idea?
You can get the image data with this method:
CanvasImageData getImageData(real sx, real sy, real sw, real sh)
Then you can check the pixel color values on the click position and decide whether or not to make a selection.
You can find additional info on how to access individual pixels here. It is for HTML canvas, but the QML canvas should be fully compatible.
...
MouseArea {
anchors.fill: parent
drag.target: parent
onClicked: {
var ctx = parent.getContext("2d")
// get the pixel
var imageData = ctx.getImageData(mouseX, mouseY, 1, 1)
// read the color data and decide whether to select or not
}
}
I have this code:
import QtQuick 2.3
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2
Dialog {
standardButtons: StandardButton.Ok | StandardButton.Cancel
width: layout.implicitWidth
height: layout.implicitHeight
RowLayout {
id: layout
anchors.fill: parent
Item {
width: 10
height: 1
}
GridLayout {
columns: 2
rowSpacing: 10
Layout.fillHeight: true
Layout.fillWidth: true
Text {
text: "Hello world? "
}
Text {
text: "Hello world!"
}
Text {
text: "Goodbye world? "
}
Text {
text: "Goodbye world!"
}
}
Item {
width: 10
height: 1
}
}
}
When you run it it looks like this, and the dialog can be resized to any size. Also the RowLayout actually doesn't fill its parent as you can see.
How can I make it so that the dialog can't be resized below the minimum size of the layout, and so that the layout fills the dialog?
Unfortunately this is a bug in Qt. Currently the documentation is misleading and Dialog does not size itself correctly to the contents. Consider this working example, which I based on the DefaultFontDialog:
AbstractDialog {
title: "Hello"
id: root
// standardButtons: StandardButton.Ok | StandardButton.Cancel
modality: Qt.NonModal
Rectangle {
id: content
implicitWidth: mainLayout.implicitWidth + outerSpacing * 2
implicitHeight: mainLayout.implicitHeight + outerSpacing * 2
property real spacing: 6
property real outerSpacing: 12
color: "white"
GridLayout {
id: mainLayout
anchors { fill: parent; margins: content.outerSpacing }
rowSpacing: content.spacing
columnSpacing: content.spacing
columns: 5
Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" }
Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" }
Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" }
Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" } Text { text: "Hello" }
}
}
}
This works exactly as expected, though of course you don't get the buttons.
If you just change it to a Dialog and uncomment the standardButtons, then it stops working - you can resize the dialog to clip its contents (width-wise at least), and the contents do not expand to the dialog size.
The reason for the minimum width not working becomes clear when we look at the source code for Dialog (in qtquickcontrols/src/dialogs/DefaultDialogWrapper.qml):
AbstractDialog {
id: root
default property alias data: defaultContentItem.data
onVisibilityChanged: if (visible && contentItem) contentItem.forceActiveFocus()
Rectangle {
id: content
property real spacing: 6
property real outerSpacing: 12
property real buttonsRowImplicitWidth: minimumWidth
property bool buttonsInSingleRow: defaultContentItem.width >= buttonsRowImplicitWidth
property real minimumHeight: implicitHeight
property real minimumWidth: Screen.pixelDensity * 50
implicitHeight: defaultContentItem.implicitHeight + spacing + outerSpacing * 2 + buttonsRight.implicitHeight
implicitWidth: Math.min(root.__maximumDimension, Math.max(
defaultContentItem.implicitWidth, buttonsRowImplicitWidth, Screen.pixelDensity * 50) + outerSpacing * 2);
minimumWidth is hardcoded to Screen.pixelDensity * 50!! There was never any hope that it would match the dialog contents. minimumHeight does work better (though not perfect, I believe because the spacing isn't considered).
I'm not sure why the defaultContentItem does not expand correctly, but anyway. It looks like the only solution at the moment is to use AbstractDialog and implement the buttons and accepted()/rejected()/etc. signals yourself. Bit of a pain.
Edit / Solution
I did some further investigation.
The reason the defaultContentItem doesn't expand is because it's bottom anchor isn't tied to the top of the button row:
Item {
id: defaultContentItem
anchors {
left: parent.left
right: parent.right
top: parent.top
margins: content.outerSpacing
}
implicitHeight: childrenRect.height
}
Minimum sizes just don't work that well with anchor-based layouts. They do with GridLayout-based layouts.
Unfortunately childrenRect has no implicitWidth/Height so we have to actually have the child items go into a ColumnLayout rather than be the ColumnLayout.
...
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
// A Dialog that resizes properly. The defualt dialog doesn't work very well for this purpose.
AbstractDialog {
id: root
default property alias data: defaultContentItem.data
onVisibilityChanged: if (visible && contentItem) contentItem.forceActiveFocus()
Rectangle {
id: content
property real spacing: 6
property real outerSpacing: 12
property real buttonsRowImplicitWidth: minimumWidth
property bool buttonsInSingleRow: defaultContentItem.width >= buttonsRowImplicitWidth
property real minimumHeight: implicitHeight
property real minimumWidth: implicitWidth // Don't hard-code this.
implicitWidth: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 10, mainLayout.implicitWidth + outerSpacing * 2))
implicitHeight: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 10, mainLayout.implicitHeight + outerSpacing * 2))
color: palette.window
Keys.onPressed: {
event.accepted = true
switch (event.key) {
case Qt.Key_Escape:
case Qt.Key_Back:
reject()
break
case Qt.Key_Enter:
case Qt.Key_Return:
accept()
break
default:
event.accepted = false
}
}
SystemPalette { id: palette }
// We use layouts rather than anchors because there are no minimum widths/heights
// with the anchor system.
ColumnLayout {
id: mainLayout
anchors { fill: parent; margins: content.outerSpacing }
spacing: content.spacing
// We have to embed another item so that children don't go after the buttons.
ColumnLayout {
id: defaultContentItem
Layout.fillWidth: true
Layout.fillHeight: true
}
Flow {
Layout.fillWidth: true
id: buttonsLeft
spacing: content.spacing
Repeater {
id: buttonsLeftRepeater
Button {
text: (buttonsLeftRepeater.model && buttonsLeftRepeater.model[index] ? buttonsLeftRepeater.model[index].text : index)
onClicked: root.click(buttonsLeftRepeater.model[index].standardButton)
}
}
Button {
id: moreButton
text: qsTr("Show Details...")
visible: false
}
}
Flow {
Layout.fillWidth: true
id: buttonsRight
spacing: content.spacing
layoutDirection: Qt.RightToLeft
Repeater {
id: buttonsRightRepeater
// TODO maybe: insert gaps if the button requires it (destructive buttons only)
Button {
text: (buttonsRightRepeater.model && buttonsRightRepeater.model[index] ? buttonsRightRepeater.model[index].text : index)
onClicked: root.click(buttonsRightRepeater.model[index].standardButton)
}
}
}
}
}
function setupButtons() {
buttonsLeftRepeater.model = root.__standardButtonsLeftModel()
buttonsRightRepeater.model = root.__standardButtonsRightModel()
if (!buttonsRightRepeater.model || buttonsRightRepeater.model.length < 2)
return;
var calcWidth = 0;
function calculateForButton(i, b) {
var buttonWidth = b.implicitWidth;
if (buttonWidth > 0) {
if (i > 0)
buttonWidth += content.spacing
calcWidth += buttonWidth
}
}
for (var i = 0; i < buttonsRight.visibleChildren.length; ++i)
calculateForButton(i, buttonsRight.visibleChildren[i])
content.minimumWidth = calcWidth + content.outerSpacing * 2
for (i = 0; i < buttonsLeft.visibleChildren.length; ++i)
calculateForButton(i, buttonsLeft.visibleChildren[i])
content.buttonsRowImplicitWidth = calcWidth + content.spacing
}
onStandardButtonsChanged: setupButtons()
Component.onCompleted: setupButtons()
}
You have to use it a bit differently to a normal Dialog. Just imagine it is a ColumnLayout (this is a slightly different example to the original question):
ColumnLayoutDialog {
id: dialog1
standardButtons: StandardButton.Ok | StandardButton.Cancel
Text {
text: "Hello world? "
}
Text {
text: "Hello world!"
}
// Spacer.
Item {
Layout.fillHeight: true;
}
Text {
text: "Goodbye world? "
}
Text {
text: "Goodbye world!"
}
}
By the way you could change the ColumnLayout to a GridLayout and expose the columns property if you want. That might make more sense.
A small issue
It turns out a QWindow's minimum width and height only ensure that the dialog isn't actively resized to be less than its content. It doesn't ensure that the dialog is never smaller than its content, because the content can grow after the dialog is created (e.g. extra items added). To workaround this I added this function to my ColumnLayoutDialog:
// The minimumWidth/Height values of content are accessed by the C++ class, but they
// only ensure that the window isn't resized to be smaller than its content. They
// don't ensure that if the content grows the window grows with it.
function ensureMinimumSize()
{
if (root.width < content.minimumWidth)
root.width = content.minimumWidth;
if (root.height < content.minimumHeight)
root.height = content.minimumHeight;
}
It has to be called manually when you change the dialog contents. Or to do it automatically you can add this to the content rectangle:
onMinimumHeightChanged: {
if (root.height < content.minimumHeight)
root.height = content.minimumHeight;
}
onMinimumWidthChanged: {
if (root.width < content.minimumWidth)
root.width = content.minimumWidth;
}
This is a bug in QT up to version 5.6.0. Most likely the bug number 49058. The code from the question works as expected in QT 5.6.1 and 5.7.0.
A partial workaround for the old versions is to remove the lines
width: layout.implicitWidth
height: layout.implicitHeight
and replace
anchors.fill: parent
with
anchors.right: parent.right
anchors.left: parent.left
The dialog then respects the minimum height and the contents expand horizontally.
Here is also a complete workaround, but it relies on undocumented implementation details of Dialog, so it should be used with caution. It works in 5.5.1, 5.6.0, 5.6.1 and 5.7.0. Note also that the second Item is changed to a red Rectangle to make the behavior more apparent.
import QtQuick 2.3
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2
Dialog {
visible: true
standardButtons: StandardButton.Ok | StandardButton.Cancel
RowLayout {
id: layout
// In the horizontal direction, expansion and shrinking can be achieved with anchors.
anchors.left: parent.left
anchors.right: parent.right
// Used only for guessing the height of the Dialog's standard buttons.
Button {
id: hiddenButton
visible: false
}
// Repeats until the relevant parts of the dialog (parent of the parent of the RowLayout)
// are complete, then overwrites the minimum width and implicit height and stops repeating.
Timer {
id: timer
interval: 50; running: true; repeat: true;
onTriggered: {
if(layout.parent.parent) {
var lp = layout.parent
var lpp = layout.parent.parent
lpp.minimumWidth = layout.implicitWidth + 2 * lpp.outerSpacing
layout.buttonHeight = 2 * lpp.outerSpacing + hiddenButton.implicitHeight + lpp.spacing
lp.implicitHeight = layout.implicitHeight + 2 * lpp.outerSpacing
running = false
}
}
}
// The guessed space needed for the Dialog's buttons.
property int buttonHeight: 80
// Expand and shrink vertically when the dialog is resized.
height: parent.parent ? Math.max(parent.parent.height-buttonHeight, implicitHeight) : implicitHeight
Item {
width: 10
height: 1
}
GridLayout {
columns: 2
rowSpacing: 10
Layout.fillHeight: true
Layout.fillWidth: true
Text {
text: "Hello world? "
}
Text {
text: "Hello world!"
}
Text {
text: "Goodbye world? "
}
Text {
text: "Goodbye world!"
}
}
Rectangle {
Layout.fillHeight: true
color: 'red'
width: 10
}
}
}