dynamical reparentig in qml - qml

I want to change dynamicaly type of qml Item without re-creation. In this example window transforms into popup window and question is how to transform it to qml Item.
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
Window {
id: myWindow
height: 300
width: 300
visible: true
MouseArea {
anchors.fill: parent
onDoubleClicked: myWindow.flags = Qt.Popup
}
}}

What are you trying to achieve?
You must understand that when you "transform" your Window into a popup Window, the actual type of your object does not change. You only set a flag, which happen to give your window a popup behavior. As to dynamically change the type of a QML object, I don't think it is even possible, and I don't see the point of it.

When I want to make a 'pupup', I use something like that
Rectangle{
id:picker
visible:false
function find_superparent( child_object) {
var fparent;
fparent=child_object.parent;
while(fparent.parent) fparent= fparent.parent;
return fparent;
}
Component.onCompleted: picker.parent=find_superparent(picker)
...
}
and, when I want to show the popup
picker.visible=true
I use this function (find_superparent) in dynamic component creation/destruction too...
this method works... I don't know if exists a better way ...

Related

How do I go directly from FullScreen to Maximized in a QML Window?

Below is a small QML application. What I intended was for the application to start full screen, and on the Escape key, change it to maximized:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
id: topLevelWindow
width: 640
height: 480
visible: true
title: qsTr("Hello World")
visibility: Window.FullScreen
Rectangle {
id: rect
anchors.fill: parent
color: "lightBlue"
focus: true
Keys.onPressed: {
if (event.key === Qt.Key_Escape) {
rect.color = "lightGreen"
topLevelWindow.visibility = Window.Maximized
}
}
}
}
What actually happens, though, is that it starts full screen as intended, but pressing Escape makes it windowed but not maximized. Pressing Escape a second time actually maximizes it.
Is there a way to do this without making the user hit Escape twice?
It looks like this is indeed a bug. Seems like it's been lingering for a while, but (some) newer versions may have fixed it?
In the meantime, it's relatively easy to add a hacky workaround:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
id: topLevelWindow
width: 640
height: 480
visible: true
title: qsTr("Hello World")
visibility: Window.FullScreen
Rectangle {
id: rect
anchors.fill: parent
color: "lightBlue"
focus: true
Keys.onPressed: {
if (event.key === Qt.Key_Escape) {
rect.color = "lightGreen"
topLevelWindow.visibility = Window.Windowed
windowHackTimer.start()
}
}
}
Timer {
id: windowHackTimer
interval: 0
repeat: false
onTriggered: {
topLevelWindow.visibility = Window.Maximized
}
}
}
On the button press it becomes windowed, and then after it returns to the event loop (with a 0ms timer), it sets it to maximized. Just setting topLevelWindow.visibility multiple times in Keys.onPressed doesn't get the job done.
I think you should (1) make sure that the Escape key is accepted by your event handler (so that it is not passed down) and (2) schedule the outcome with Qt.callLater.
Keys.onPressed: {
if (event.key === Qt.Key_Escape) {
event.accepted = true;
Qt.callLater( greenRectAndMaximize );
}
}
function greenRectAndMaximize() {
rect.color = "lightGreen";
topLevelWindow.visibility = Window.Maximized;
}
The event.accept() is important to ensure that no other UI will handle the same event. That could be the cause of your problem. The Qt.callLater is important because it ensures that your action is added to the end of the windows messaging queue so that the UI/UX for the Escape key (and any other UI/UX events can complete) before we do our action.
Generally, whenever processing events, key presses, button clicks, and so forth, think about what needs to happen now and what needs to be queued for later.
In your case, you have a simple action, but, imagine something more complex such as a button click that triggers a page transition and a sort of 10000 records. The UI/UX is the user clicks the button and we want to see the button animate down and up fully before the action kicks off. If we did it during the event handler, the button may appear to be stuck in the down portion of the animation and the app will appear momentarily hang/crash. So, it is important to understand when we need to queue up actions.
Qt.callLater is one of the easiest ways to separate the UI/UX event and the user action and can improve the perceptual responsiveness of your application.

How Can I Scroll the Images In QML Automatically?

I have a ListView Containing only Images. I assigned the orientation of ListView as horizontal Direction. How can I change, i.e. scroll, the images automatically with some time gap?
Use a Timer. When it is triggered, update the currentIndex of the ListView. This will scroll automatically with default animations. Finally, according to the documentation, positionViewAtIndex is
The correct way to bring an item into view is with positionViewAtIndex
Indeed the method provides a more fine-grained control over the appearance of Items via the PositionMode parameter. See the documentation for further details.
Minimal example:
import QtQuick 2.5
import QtQuick.Window 2.0
Window {
visible: true
width: 200
height: 15
ListView {
id: list
anchors.fill: parent
orientation: ListView.Horizontal
model: 10
delegate: Text {
width: 40
id: name
text: index
}
}
Timer {
interval: 500
repeat: true
running: true
onTriggered: {
//list.currentIndex += 1 // this...
//list.incrementCurrentIndex() // ...or this!
//list.positionViewAtIndex(list.currentIndex, ListView.Center)
}
}
}

How are implicit dimensions of QtQuick items propagated?

I am trying to implement a component which should by default (if no width was explicitly set) take up as much space as it needs (i.e. depending on its implicitWidth). And if width was set at definition it should shrink its contents to fit in the provided area.
Here's an example:
import QtQuick 2.2
import QtQuick.Window 2.0
Window {
width: 200
height: 100
visible: true
property bool restricted: false
Component {
id: external
FocusScope {
implicitWidth: column.implicitWidth
implicitHeight: column.implicitHeight
focus: true
Column {
id: column
width: parent.width > 0 ? parent.width : undefined
Text {
id: label
width: parent.width > 0 ? parent.width : undefined
elide: Text.ElideRight
font.pixelSize: 24
text: "1234567890"
}
}
Keys.onRightPressed: label.text += label.text
}
}
Loader {
width: restricted ? 100 : undefined
sourceComponent: external
focus: true
Keys.onReturnPressed: restricted = !restricted
}
}
In this sample two modes are controlled by auxiliary bool property, and I want it to support two forms of declaration:
Explicit width. Text should elide.
Loader {
width: 100
sourceComponent: external
focus: true
}
Loader width should be enough to fit the whole text without eliding.
Loader {
sourceComponent: external
focus: true
}
Motivation is that such a component will be defined in a separate file and is being designed to be placed in different parts of UI with both behaviors desired depending on current needs. This sample with inline component declaration is only for demonstration purpose.
UPDATE:
The following trick parent.width > 0 ? parent.width : undefined works, but only for initial setup. If component contents change and implicitWidth is updated (in an unrestricted mode) the width of the component does not change (i.e. Text remains elided).
For example, press right key just right after launching example. You should see that Text has become elided, but its width did not increased
twice regardless the fact that string was duplicated.

Dynamically set Label's "id" property

I'm developing an application for SailfishOS using the QML language.
I want to dynamically set the id property of a Label by using an if condition.
This is my code:
Label {
id: {
if(myBool == false) {
thisText()
} else {
notThatText()
}
}
width: parent.width
horizontalAlignment: Text.AlignRight
text: ""
font.pixelSize: Theme.fontSizeLarge
}
This code is placed into my CoverPage.qml file, the one that display things on the application's cover while in background.
By doing this, the cover is simply black, nothing is displayed.
Is it possible in QML to do this?
Thanks in advance!
The Qt doc says this.
While it may look like an ordinary property, the id attribute is not an ordinary property attribute, and special semantics apply to it;
You cannot set the id of a QML component at runtime.(Correct me if I am wrong). You might find objectName property useful. But I don't understand why you are trying to assign dynamic id.
I have a use case where use a dynamic/specific id could be useful. The id could be view with Gammaray, it can help for debugging.
GridLayout {
id: layout
Repeater {
model: foo
Bar {
id: bar_X_Y // bar_{model.row}_{model.column}
}
}
}
But as far as I know, it's not possible.

Disabling resize on Dijit Simple Text Area?

I'm using Dojo 1.9 to start learning, and I'm having trouble disabling the resize of the Simple Textarea. I don't really have a particular need to do this, I was just curious about how to and have since been unable.
There is no property listed in the Dijit API, and changing the CSS either with .set("style"), including it inline in the original container (I'm doing it programmatically), or even trying to set resize to none in the original declaration ie:
var textarea = new SimpleTextarea({
rows: 5,
cols: 10,
onFocus: function(){ console.log("textarea focus handler"); },
onBlur: function(){ console.log("textarea blur handler"); },
selectOnClick: true,
style: "resize=none",
value: "This is a sample SimpleTextarea."
}, "textarea");
Any ideas?
If you set style equal to an object with a key value pair of resize : "none" that will do the trick
var textarea = new SimpleTextarea({
style: {resize : "none"}
}, "textarea");
You can do like this:
<input dojotype="dijit.form.SimpleTextarea"
id="yourTxtWidget"
style="resize:none; width: 230px; height: 75px;"
class="myTextField"/>