Make child object be always on top - qt

I was wondering either the following functionality is available in QML: I need for a child object (a text here) to always stay on top of other object, no matter the child/ parent connection. Here is a MWE:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle
{
id: rectMain;
anchors.centerIn: parent
width: parent.width
height: parent.height
color: "white"
Rectangle
{
id: rect1;
width: 200;
height: 200;
x: 100;
y: 100;
color: "red";
Text
{
id: theText;
text: qsTr("text");
anchors.centerIn: parent;
}
}
Rectangle
{
id: rect2;
width: 200;
height: 200;
x: 200;
y: 200;
color: "yellow";
}
}
}
It will show this window:
As you can see the "text" is covered with rec2, as it's a child of rect1, which was created prior to rect2. Is it possible for the text to be always on top of rect2 with current parent/ child connection?

This is the idea I expressed above. But I really can imagine for myself how that could be used. If you could define your real goals we will find another solution, of course.
import QtQuick 2.11
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
width: 400
height: 400
visible: true
title: "Example"
Item {
z: 1
Repeater {
id: rectGenerator
property bool loaded: false
Component.onCompleted: rectGenerator.loaded = true
model: 10
delegate: Rectangle {
width: 100
height: 100
color: Qt.rgba(Math.random(),Math.random(),Math.random(),0.8)
x: Math.round(Math.random() * 300)
y: Math.round(Math.random() * 300)
Drag.active: dragArea.drag.active
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
}
}
}
}
Loader {
z: 2
sourceComponent: Repeater {
model: rectGenerator.model
delegate: Text {
x: rectGenerator.itemAt(index).x
y: rectGenerator.itemAt(index).y
width: 100
height: 100
text: "item " + (index + 1)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
active: rectGenerator.loaded
}
}

Related

Dragging from Listview to a droparea

I am following this example here Using drag and drop with ListView to create an inventory UI. However, I have broken down the components into a main section, Listview and a droparea. Everything is working except, I cannot get the ReferenceError: listView is not defined. Please help
Main area
import QtQuick 2.15
import QtQuick.Controls 2.15
Page{
id:dragRect
Rectangle {
id: root
width: 400
height: 400
ListViewElem{
}
DropAreaElem{}
}
}
ListViewElem
import QtQuick 2.15
ListViewElem {
id: listView
width: parent.width / 2
height: parent.height
property int dragItemIndex: -1
model: ListModel {
Component.onCompleted: {
for (var i = 0; i < 10; ++i) {
append({value: i});
}
}
}
delegate: Item {
id: delegateItem
width: listView.width
height: 50
Rectangle {
id: dragRect2
width: listView.width
height: 50
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "salmon"
border.color: Qt.darker(color)
Text {
anchors.centerIn: parent
text: modelData
}
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: dragRect2
drag.onActiveChanged: {
if (mouseArea.drag.active) {
listView.dragItemIndex = index;
}
dragRect2.Drag.drop();
}
}
states: [
State {
when: dragRect2.Drag.active
ParentChange {
target: dragRect2
parent: root
}
AnchorChanges {
target: dragRect2
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
}
}
]
Drag.active: mouseArea.drag.active
Drag.hotSpot.x: dragRect2.width / 2
Drag.hotSpot.y: dragRect2.height / 2
}
}
}
DropAreaElem
import QtQuick 2.15
Rectangle {
width: parent.width / 2
height: parent.height
anchors.right: parent.right
color: "#aaff0011"
DropArea {
id: dropArea
anchors.fill: parent
onDropped: {
listView.model.remove(listView.dragItemIndex);
listView.dragItemIndex = -1;
}
}
}
You should provide id to your components
import QtQuick 2.15
import QtQuick.Controls 2.15
Page{
id:dragRect
Rectangle {
id: root
width: 400
height: 400
ListViewElem{
id: listView
}
DropAreaElem{
id: dropArea
}
}
}

Choreography in qml

Is there possible to use choreography animations in qml (in a REUSABLE manner)?
for example in StackView transitions from page1 to page2.
I tried following code, but ParentChange does not work as expected. This code just changes red rectangle's position.
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
StackView {
id: stack
anchors.fill: parent
initialItem: Page {
id: page1
Label {
text: qsTr("First page")
anchors.centerIn: parent
}
Rectangle {
id: rect
width: 50
height: 50
x: 600
y: 100
color: "red"
states: [
State {
when: stack.depth > 1
ParentChange { target: rect; parent: stack.currentItem; x: 100; y: 100; }
}
]
transitions: Transition {
ParentAnimation {
NumberAnimation { properties: "x,y"; duration: 1000 }
}
}
}
MouseArea {
anchors.fill: parent
onClicked: stack.push(page2)
}
}
Component {
id: page2
Page {
background: Rectangle { color: "yellow"; anchors.fill: parent }
Label {
text: qsTr("Second page")
anchors.centerIn: parent
}
}
}
}
Rectangle {
id: back
color: "blue"
width: 50
height: 50
radius: 25
MouseArea {
anchors.fill: parent
onClicked: stack.pop()
}
}
}
but the usage is not limited to StackView. It can be used in many other situations. (just like above link)

Qt Quick layout changes on different events

When I execute my QML code, the output is:
When I minimize the window, It becomes like
and finally, when I again maximize the window it changes to
the GUI which I want to make looks like
![][5]
I am not getting what is the issue for all of the changes in GUI at different events. And this is the Qml code which I wrote
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 1080
height: 720
title: qsTr("Login")
GridLayout{
Rectangle{
id:one
Rectangle
{ id:two
color:"black";
width: 700
height:40
}
Image {
id: image
x: 470
y: 0
width: 54
height: 42
source: "qrc:/user.png"
}
Rectangle
{
id:three;
color:"#f47a42";
width: 200
height:40
anchors.left:two.right;
anchors.margins:940
Text {
id: user
text: qsTr("4200")
color:"white"
anchors.top: value.bottom
}
Text
{
id: value;
text: qsTr("User");
color:"yellow"
}}
}
}
Rectangle{
ColumnLayout{
width: 50
height: childrenRect.height+fillHeight;
}
color:"green"
}
}
So why this is happening and how can I solve this problem?
Output of the code below
Here is example of scalable window:
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Layouts 1.11
Window {
visible: true
width: 800
height: 600
title: qsTr("Layout example")
ColumnLayout{
spacing: 0
anchors.fill: parent
Item {
id: titlebar
Layout.preferredHeight: 40
Layout.fillWidth: true
RowLayout {
anchors.fill: parent
spacing: 0
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "orange"
Text {
anchors.centerIn: parent
text: "Title"
}
}
Rectangle {
Layout.preferredWidth: 100
Layout.fillHeight: true
color: "lightgreen"
Text {
anchors.centerIn: parent
text: "Actions"
}
}
}
}
Rectangle {
id: content
Layout.fillHeight: true
Layout.fillWidth: true
color: "lightyellow"
Text {
anchors.centerIn: parent
text: "Content"
}
}
}
}

QML pieMenu on draggable object

I've got a draggable object that is created by a Javascript, which is working fine. But when I create a PieMenu inside it, the object isn't created/visible in the Javascript context:
import QtQuick 2.8
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4
import QtQml.Models 2.2
Rectangle {
id: rev
width: 100
height: 80
color: "transparent"
antialiasing: false
Drag.active: dragArea.drag.active
MouseArea {
id: dragArea
width: parent.width
height: parent.height + 10 // easier to get
anchors.centerIn: parent
drag.target: parent
drag.axis: Drag.XAndYAxis
onClicked: pieMenu.popup(mouseX, mouseY), console.log("clicked")
}
PieMenu {
id: pieMenu
MenuItem {
text: "Add vertical bar"
onTriggered: print("Action 2")
}
}
Gauge {
id: revgauge
anchors.fill: parent
anchors.margins: 10
orientation : Qt.Horizontal
minorTickmarkCount: 4
tickmarkStepSize : 5000
minimumValue: 0
maximumValue: 10000
Behavior on value {
NumberAnimation {
duration: 5
}
}
Text {
font.pixelSize: (parent.height / 3)
anchors.top : parent.top
font.bold: true
font.family: "Eurostile"
color: "white"
anchors.horizontalCenter: parent.horizontalCenter
}
style: GaugeStyle {
valueBar: Rectangle {
implicitWidth: rev.height /3
color: Qt.rgba(revgauge.value / revgauge.maximumValue, 0, 1 - revgauge.value / revgauge.maximumValue, 1)
}
}
}
}
Can Mousearea handle dragging and a PieMenu at once? If not how can it be solved?
Consider QML PieMenu boundingItem. It addresses an exact issue with MouseArea you presented.

How to integrate ListView with FolderListModel using QML?

I am developing a file browser interface using QML. However, I find I cannot click any folder and the list covered the top button. I don't know what I did wrongly.
I used ListView and FolderListModel during the development. And I intend to make the interface as below and works like a file browser
The expected interface:
Source Code:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Window 2.1
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.1
import Qt.labs.folderlistmodel 2.1
import QtMultimedia 5.0
import QtQuick.Controls.Styles 1.4
import Qt.labs.platform 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
property int index: 0
property bool isActive: true
SwipeView {
id: swipeView
anchors.fill: parent
currentIndex: tabBar.currentIndex
Page1 {
Rectangle {
id:root;
state:"hidden";
color: "#212126";
property string folderPathName: "file:///C:/";
property bool rootPath:false;
signal message(string msg);
property int lineHeight: 90;
signal selectedFolder(string folderPath);
Button{
id:topLine;
text: "...";
width: root.width;
height: root.lineHeight;
onClicked: {
if (folderModel.parentFolder != ""){
root.folderPathName = folderModel.parentFolder;
}
else{
root.state = "hidden";
}
}
}
ListView{
id:listFileView;
anchors{
bottom: rectangleButton.top;
bottomMargin: 4;
right: root.right;
rightMargin: 0;
left: root.left;
leftMargin: 0;
top: topLine.bottom;
topMargin: 0;
}
clip:true;
delegate:Button{
text: fileName;
height:root.lineHeight;
width:root.width;
onClicked: {
if(folderModel.isFolder(index)){
root.folderPathName = folderModel.get(index, "fileURL");
}
}
}
model: FolderListModel{
id:folderModel;
objectName: "folderModel";
showDirs: true;
showFiles: true;
showDirsFirst: true;
nameFilters: ["*.mp3", "*.flac"];
folder:root.folderPathName;
}
}
Rectangle {
id: rectangleButton;
height: 20;
color: "#212126";
anchors{
left: root.left;
leftMargin: 0;
right: root.right;
rightMargin: 0;
bottom: root.bottom;
bottomMargin: 0;
}
Rectangle{
id:rectWhiteLine;
anchors{
left:parent.left;
right: parent.right;
top:parent.top;
}
height: 2;
color:"white";
}
}
}
}
Page {
}
}
footer: TabBar {
id: tabBar
currentIndex: swipeView.currentIndex
TabButton {
text: qsTr("Main")
}
TabButton {
text: qsTr("View")
}
}
}
After changing anchors{ bottom: rectangleButton.top; bottomMargin: 4; right: root.right; rightMargin: 0; left: root.left; leftMargin: 0; top: topLine.bottom; topMargin: 0; } to width: 200; height: 600, the interface turns to be below:
The folders cannot be clicked and they are not correctly aligned.
Maybe this example would be of any use to you.
I have added "back" button that goes up one folder, and buttons that represent folders inside ListView are colored orange.
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Window 2.2
import Qt.labs.folderlistmodel 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
id: mainRect
x: 20
y: 20
width: 300
height: 450
border.color: "black"
radius: 30
ListView {
y: 30
width: parent.width
height: parent.height - 60
clip: true
model: FolderListModel {
id: folderListModel
showDirsFirst: true
// nameFilters: ["*.mp3", "*.flac"]
}
delegate: Button {
width: parent.width
height: 50
text: fileName
onClicked: {
if (fileIsDir) {
folderListModel.folder = fileURL
}
}
background: Rectangle {
color: fileIsDir ? "orange" : "gray"
border.color: "black"
}
}
}
}
Button {
anchors.left: mainRect.right
anchors.leftMargin: 5
text: "back"
onClicked: folderListModel.folder = folderListModel.parentFolder
}
}
To get clickable top area with "..." I would add Text there and Mouse Area to handle clicks:
Text {
width: parent.width
height: 30
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: "..."
MouseArea {
anchors.fill: parent
onClicked: folderListModel.folder = folderListModel.parentFolder
}
}
Add this code inside mainRect i.e. after line radius: 30.

Resources