Put rectangle in the center of display - qt

I have one Item in one of my QML components and I need to know how to set x and y to put this rectangle in the center of the Display, whatever is the parent component, I just need put this particular Item in the center every time. I have tried with Screen component but I cannot set properly. Any idea?
This is my component:
Component {
id: example
CustomItem {
id: itemExample
}
}
What I need to set in CustomItem qml file to ensure that when I instance this component WHEREVER (in wherever parent), this CustomItem appears in on the center of display and on top of all other components?
EDIT: CustomItem is an Item and it not possible to use Window or ApplicationWindow.

Related

How to get notified when a QML item's dimensions change?

I understand that I can get to know if the width or height of a QML item changed using the slots onWidthChanged and onHeightChanged. This is by doing something like below.
import QtQuick 2.12
Item {
id: my_item
onWidthChanged: {
if (my_item.visible) {
console.log("Dimension chnaged")
}
}
onHeightChanged: {
if (my_item.visible) {
console.log("Dimension chnaged")
}
}
}
Above works well. But I am only interested to know if the dimension of my QML item changed. I just need a callback when width or the height changed. I don't need a callback for both.
Is there a QML signal to listen only for a dimension change?
I am using Qt 5.15.7 commercial version.
As a workaround, you can create a property which is bound to both width and height and connect a handler to the changed signal of that property:
property double dimensions: width * height
onDimensionsChanged: {
if(my_item.visible)
console.log("Dimension changed")
}
There is a small risk, namely the number won't change when swapping width & height, but that might be worth it in your situation
As mentioned in the comments no such signal currently exists by default.
You can create a size or rect type property and react on that instead though:
property size dimensions: Qt.size(width, height)
onDimensionsChanged: console.log("Dimension changed")
Here's a WASM example of it working to power an emitter:
https://www.canonic.com/#https://playground.canonic.com/525f6691-fe05-4824-a7f1-574bb8cabd8b/dimension-changed-signal-example

QML StackView : Changing replaceEnter/Exit animation dynamically

Is there anyway to change the replaceEnter/Exit Transition animation dynamically depending on the next QML file to be loaded in the stack view.
Situation:
I have a Centre QML file having 4 buttons on the 4 sides of the screen. There are other 4 QML files namely Top, Bottm, Right and Left. On press of top button on the Centre QML the Top qml file should transitioned from top-to-bottom and replace the centre one. Similarly on press of left button on the centre QML the left QML should enter there display area from left to right and replace the centre one.
I tried using replaceEnter/Exit property. But not able to understand how to change it dynamically depending on the next QML to be displayed.
take a look at the doc for infos about customizing transitions for Stackview.
If you need more than one transition you can define them separately and then assign them just before they are used. Here is an example:
StackView {
id: control
pushEnter: topTransition
Transition {
id: topTransition
XAnimator {
from: (control.mirrored ? -1 : 1) * -control.width
to: 0
duration: 400
easing.type: Easing.OutCubic
}
}
Transition {
id: bottomTransition
XAnimator {
from: 0
to: (control.mirrored ? -1 : 1) * control.width
duration: 400
easing.type: Easing.OutCubic
}
}
Button {
text: "Push page from bottom"
onClicked: {
control.pushEnter = bottomTransition
control.push(bottomPage)
}
}
}
You will have to explicitly set all push/pop/replace transitions you need before each button click.

Trying to style Qt QML items by inserting child styling item

I'm trying different approaches to styling a QT's app QML items. My goal is to:
limit the amount of code in the main files (hide all styling stuff in styling files, unlike in the Style Singleton approach)
not have to define every single type of item I'm going to use (unlike in the Custom Component approach)
possibly be able to mix and match different pre-defined styles in a single item.
Maybe there is a clear strategy to get this, I just didn't read about it yet. And maybe it doesn't make any sense anyway :-)
I've been playing with the idea of defining different components, one for each style type I want to define. The idea is to:
- define a component which is going to modify its parent
- insert that component where I want to adopt that specific style
A first approach relies on some javascript calls:
MyStyle.qml:
Item {
Component.onCompleted: {
parent.color = "lightblue"
parent.radius = 5
parent.border.width = 3
parent.border.color = "black"
}
}
And in my main code:
Rectangle {
id: testRectangle
anchors.fill: parent
MyStyle {}
}
This gives me the result I want, but it doesn't feel right:
I'd like for the styling to be applied statically, once and for all
if I start using this all over the place, won't I see artifacts when objects get created, and slow down my interface?
So I tried this too:
MyRectangleStyle.qml:
Item {
property Rectangle styleTarget
styleTarget.color: "lightblue"
styleTarget.radius: 5
styleTarget.border.width: 3
styleTarget.border.color: "black"
}
and in my main code:
Rectangle {
id: testRectangle
anchors.fill: parent
MyStyle {styleTarget: testRectangle}
}
But:
well, it doesn't work :-) (no warnings though, qml simply doesn't load)
and I'm sort of back to having to define every single type of items I'm going to use.
So, is there a better way to achieve what I'm trying to do here? Thanks!
Your second method does not work because your Component sets properties to an item that does not necessarily exist at the time of creating the Component, instead it sets the property when the styleTarget changes. On the other hand, it is not necessary for MyStyle to be an Item since it is not shown, instead use QtObject, and finally to generalize your method change property Item styleTarget toproperty Rectangle styleTarget:
QtObject {
property Item styleTarget
onStyleTargetChanged: {
styleTarget.color = "lightblue"
styleTarget.radius = 5
styleTarget.border.width = 3
styleTarget.border.color= "black"
}
}

How to remove bounds of the Flickable QML component?

I want to display a large amount of content, for example, a grid of multiple images inside a window that is smaller than the content, similar to a geographical map but instead of a map, I want my own components as the "map". For this minimal working example, let's take for the content a grid of images with a total size of 1000x1000 with a window into this content of only 300x300.
I have tried 2 different approaches, but I will only go into detail of the first approach as that is the one that got me closest to my desired result:
I have tried the Flickable component but the content cannot be moved outside the predefined bounds, making the user unable to move the view in order to display all the parts of the content. So the simplest solution that I'm thinking about now is if I could remove these bounds from the Flickable component, but how?
I have also tried the Map component but it requires a "plugin" and I was unable to figure out how to use this component with my own content of an image grid.
The content that I want to show is something this
Grid {
columns: 5
spacing: 2
Repeater {
model: ListModel {
ListElement {
path: 'test1'
}
ListElement {
path: 'test2'
}
// ...
ListElement {
path: 'test25'
}
}
Rectangle {
width: 200
height: 200
Image {
anchors.fill: parent
source: 'file:' + path
}
}
}
}
I tried, putting this inside the Flickable like this
Flickable {
anchors.centerIn: parent
width: 300
height: 300
contentWidth: 1000
contentHeight: 1000
clip: true
// INSERT CUSTOM GRID COMPONENT HERE
}
This results in a 300x300 view inside the content as expected, but once you start to flick through the content to view different parts of it, you are stopped by the bounds preventing you from seeing anything outside these bounds. You can see it while dragging but once you release the view of the content is reset to these bounds.
So how do I remove these bounds? (Or is there a different component more suitable for my application?)
Here is a gif that shows how the content can be dragged passed the bounds, but once released it will only go up to the bounds and not further
I found the issue, I set the contentWidth and contentHeight of the Flickable incorrectly, this example works fine. The contentWidth and contentHeight determine the bounds in which you can flick.

QML avoid empty spaces when Drag and Drop Between Views

I am using the QtQuick's Drag and Drop example (the Tiles part) to drag and drop tiles (representing buttons) from the list onto the grid as a way to dynamically lay out these buttons.
When "removing" (i.e. reparenting) the tile from the list, an empty space is left. I would like the list to automatically reorganize to close this gap. Is that possible using the approach in the example where the drag/drop is simply done by reparenting the tile? Or do I need to have two models (one for the list and one for the grid) and add/remove the dragged item between the two models?
Thanks for your help!
See this image
to get a better idea of what I mean.
It happens because in the example they just apply a parent change on a child of the tile, so the empty root Item remains in the columns:
// DragTile.qml
Item {
id: root
// ...
MouseArea {
// ...
drag.target: tile
onReleased: parent = tile.Drag.target !== null ? tile.Drag.target : root
Rectangle {
id: tile
// ...
}
}
}
If you apply the parent change to the root Item, the Column will automatically be reorganized:
onReleased: {
if (tile.Drag.target) {
root.parent = tile.Drag.target
root.anchors.centerIn = root.parent
}
}

Resources