QML simple program not running - qt

I am trying to run the following, but nothing happens when I run it.
How can I debug such an issue?
import QtQuick 2.0
import QtQml.Models 2.1
Item{
id: main
width: 1500
height: 1500
GridView {
id: root
width: 1500
height: 1500
cellWidth: 200; cellHeight: 200
visible: true
model: DelegateModel {
model: ListModel {
ListElement {
color: "blue"
}
ListElement {
color: "white"
}
ListElement {
color: "red"
}
ListElement {
color: "green"
}
ListElement {
color: "orange"
}
ListElement {
color: "yellow"
}
ListElement {
color: "grey"
}
}
delegate: MouseArea {
objectName: "mousearea"
implicitHeight: parent.height
implicitWidth: parent.width
Rectangle {
anchors.fill: parent
color: model.color
}
drag{
target: parent
}
}
}
}
}
What I intend from this code is the following:
create few rectangles inside a GridView and add a MouseArea to them and try dragging them around afterwards. I am not sure if my model structure is correct here.
EDIT:
Adding main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}

QQmlApplicationEngine expects to have a Window as the root element as indicated by the docs:
...
Unlike QQuickView, QQmlApplicationEngine does not automatically create
a root window. If you are using visual items from Qt Quick, you will
need to place them inside of a Window.
...
So the solution is simple, change Item by Window:
main.qml
import QtQuick 2.0
import QtQuick.Window 2.11
import QtQml.Models 2.1
Window{
visible: true
id: main
width: 1500
height: 1500
GridView {
id: root
width: 1500
height: 1500
cellWidth: 200; cellHeight: 200
visible: true
model: DelegateModel {
model: ListModel {
ListElement {
color: "blue"
}
ListElement {
color: "white"
}
ListElement {
color: "red"
}
ListElement {
color: "green"
}
ListElement {
color: "orange"
}
ListElement {
color: "yellow"
}
ListElement {
color: "grey"
}
}
delegate: MouseArea {
objectName: "mousearea"
implicitHeight: parent.height
implicitWidth: parent.width
Rectangle {
anchors.fill: parent
color: model.color
}
drag{
target: parent
}
}
}
}
}

Related

QML: how to scroll scrollview using the mouse wheel

I need to ensure that the ListView scrolls not only when hovering over it, but also in the area around it. As in the picture
I tried to do it like this, but scrolling with the mouse wheel still doesn't work
import QtQuick 2.0
import QtQuick.Controls 2.3
Rectangle {
height: 400
width: 300
color: "steelblue"
ScrollView {
anchors.fill: parent
wheelEnabled: true
ListView {
id: listView
anchors { fill: parent; margins: 40}
clip: true
model: appModel
delegate: Rectangle {
height: 50
width: listView.width
color: colorR
}
}
}
ListModel {
id: appModel
ListElement { colorR: "red"}
ListElement { colorR: "green"}
ListElement { colorR: "blue"}
ListElement { colorR: "cyan"}
ListElement { colorR: "yellow"}
ListElement { colorR: "blue"}
ListElement { colorR: "lightgray"}
ListElement { colorR: "red"}
ListElement { colorR: "green"}
ListElement { colorR: "blue"}
ListElement { colorR: "cyan"}
ListElement { colorR: "yellow"; }
ListElement { colorR: "lightgray"}
}
}
You can use WheelHandler outside the ListView
import QtQuick
import QtQuick.Controls
Rectangle {
height: 400
width: 300
color: "green"
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
WheelHandler {
onWheel: (event)=>{listView.flick(0, event.angleDelta.y*event.y)}
}
ListView {
id: listView
anchors { fill: parent; margins: 40}
model: 50
spacing: 10
delegate: Rectangle {
height: 50
width: listView.width
color: getRandomColor()
}
}
}
You can try this online.

Glitching when dragging

I have a very simple code for drag and drop in qml.
But when you are dragging the rectangle while holding mouse the screen of window is glitched! and sometimes the color of some Rectangle vanishes.
Like this bug is reported, but not answered.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.14
import QtQml.Models 2.1
Window {
id: mainWindow
width: 700
height: 800
visible: true
color: 'grey'
Item {
anchors.fill: parent
GridView {
id: root
width: 320; height: 480
cellWidth: 80; cellHeight: 80
pixelAligned: true
displaced: Transition {
NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }
}
model: DelegateModel {
id: visualModel
model: ListModel {
id: colorModel
ListElement { color: "blue" }
ListElement { color: "green" }
ListElement { color: "red" }
ListElement { color: "yellow" }
ListElement { color: "orange" }
ListElement { color: "purple" }
ListElement { color: "cyan" }
ListElement { color: "magenta" }
ListElement { color: "chartreuse" }
ListElement { color: "aquamarine" }
ListElement { color: "indigo" }
ListElement { color: "black" }
ListElement { color: "lightsteelblue" }
ListElement { color: "violet" }
ListElement { color: "grey" }
ListElement { color: "springgreen" }
ListElement { color: "salmon" }
ListElement { color: "blanchedalmond" }
ListElement { color: "forestgreen" }
ListElement { color: "pink" }
ListElement { color: "navy" }
ListElement { color: "goldenrod" }
ListElement { color: "crimson" }
ListElement { color: "teal" }
}
delegate: DropArea {
id: delegateRoot
width: 80; height: 80
onEntered: visualModel.items.move(drag.source.visualIndex, icon.visualIndex)
property int visualIndex: DelegateModel.itemsIndex
Binding { target: icon; property: "visualIndex"; value: visualIndex }
Rectangle {
id: icon
property int visualIndex: 0
width: 72; height: 72
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter
}
radius: 3
color: model.color
Text {
anchors.centerIn: parent
color: "white"
text: parent.visualIndex
}
DragHandler {
id: dragHandler
}
Drag.active: dragHandler.active
Drag.source: icon
Drag.hotSpot.x: 36
Drag.hotSpot.y: 36
states: [
State {
when: icon.Drag.active
ParentChange {
target: icon
parent: root
}
AnchorChanges {
target: icon
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
}
}
]
}
}
}
}}
}
Before:
After:
With add attribute of open-gl in main.cpp
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#SAt looks like you found the issue with your rendering engine. Sometimes there are quirks like that in your graphics card and may require updating your graphics driver. Otherwise, as you found, see the other rendering options with QCoreApplication::setAttribute() or by setting the QT_OPENGL environment variable:
Qt::AA_UseDesktopOpenGL Equivalent to setting QT_OPENGL to desktop.
Qt::AA_UseOpenGLES Equivalent to setting QT_OPENGL to angle.
Qt::AA_UseSoftwareOpenGL Equivalent to setting QT_OPENGL to software.
References:
https://doc.qt.io/qt-6/qcoreapplication.html#setAttribute
https://doc.qt.io/qt-6/qt.html#ApplicationAttribute-enum
https://doc.qt.io/qt-5/windows-requirements.html#graphics-drivers
I test your code in my system and it works well.
My OS is Ubuntu 20.04.
My Qt Version is 5.15.2 and 6.2.3 I checked in both.
This is the Result:

How to make a menu with a submenu in qml?

I'm trying to do a menu that might have submenus for some of its options.
The behavior i want it to have is the same we see on most of websites.
When we hover an option that has a submenu, that submenu it will happear, if the mouse arrow goes anywhere else that is not the submenu the submenu will close.
I'm going to illustrate with images.
When we enter the submenu we have this:
Now we hover the Language option its submenu will happear
Now what is not done is the behavior i want. If we are hovering on the Languageoption the submenu is visible. If i go directly from language to the language's submenu it will remain there as intented.
The code of this example is provided below:
main.qml
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import QtQuick.Window 2.3
ApplicationWindow {
visible: true
width: 640
height: 500
title: qsTr("Tabbars")
Button{
id: button
text: "Menu"
onClicked: contextMenu.open()
anchors.top:parent.top
anchors.left:parent.left
height: 20
width: 100
}
Menu {
id: contextMenu
y: button.height
padding: 1
background: Rectangle {
implicitWidth: 200
border.color: "#fff"
color: "#000"
}
Button {
id: languageMenuItem
text: qsTr("Language")
width:parent.width
height: 35
background: Item {
Rectangle {
anchors.fill: parent
color: "#555"
opacity: mouseArea1.pressed ? 1 : mouseArea1.containsMouse ? 0.6 : 0.0
MouseArea {
id: mouseArea1
anchors.fill: parent
hoverEnabled: true
onEntered: function() {
submenuLanguage.open()
}
onExited: function() {
}
}
}
}
contentItem: Text {
text: languageMenuItem.text
color: "#fff"
font.pointSize: 12
font.bold: true
}
Rectangle {
z: 1
color: "#000"
opacity: 0.5
anchors.fill: parent
visible: !parent.enabled
}
Component.onCompleted: {
mouseArea1.clicked.connect(clicked)
}
}
CMenuItem{
text: qsTr("Exit")
width: parent.width
onClicked: close()
}
}
Menu {
id:submenuLanguage
x: contextMenu.width
background: Rectangle {
implicitWidth: 200
border.color: "#fff"
color: "#000"
}
Connections {
target: mouseArea1
onExited: {
console.log("mouseArea leaving")
}
}
CMenuItem{
id:btlingen
width: parent.width
text: qsTr("English")
onClicked: {
contextMenu.close()
console.log("English")
}
}
CMenuItem{
id:btlingpt
width: parent.width
text: qsTr("Português")
onClicked: {
contextMenu.close()
console.log("Português")
}
}
CMenuItem{
id:btlinges
width: parent.width
text: qsTr("Español")
onClicked: {
contextMenu.close()
console.log("Español")
}
}
CMenuItem{
id:btlingit
width: parent.width
text: qsTr("Italiano")
onClicked: {
contextMenu.close()
console.log("Italiano")
}
}
CMenuItem{
id:btlingde
width: parent.width
text: qsTr("Deutsch")
onClicked: {
contextMenu.close()
console.log("Deutsch")
}
}
}
}
CMenuItem.qml
import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQuick.Controls.Styles 1.4
MenuItem {
id: mainMenuItem
background: Item {
Rectangle {
anchors.fill: parent
color: "#555"
opacity: mouseArea.pressed ? 1 : mouseArea.containsMouse ? 0.6 : 0.0
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
}
}
}
contentItem: Text {
text: mainMenuItem.text
color: "#fff"
font.pointSize: 12
font.bold: true
}
Rectangle {
z: 1
color: "#000"
opacity: 0.5
anchors.fill: parent
visible: !parent.enabled
}
Component.onCompleted: {
mouseArea.clicked.connect(clicked)
}
}
How can i do this?
Use the cascade property to create a nested menu:
ApplicationWindow {
id: window
width: 320
height: 260
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("&Foo")
Menu {
cascade: true // Nested menu
title: qsTr("&Bar")
Action { text: qsTr("A1") }
Action { text: qsTr("A2") }
Action { text: qsTr("A3") }
}
}
}
}

QML DelegateModel: Access DelegateModel from delegate

I'm trying to create a ListView with different delegates and a drag'n'drop functionality. The delegates shall be loaded with a Loader.
The QML Documentation provides a working example for a ListView without a Loader:
http://doc.qt.io/qt-5/qtquick-tutorials-dynamicview-dynamicview3-example.html
However, using the Loader I get the error: Cannot read property 'DelegateModel' of undefined
I do not understand how I can access the DelegateModel from the Loader.
A hint to the solution is highly appreciated!
main.qml:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
import QtQuick.Dialogs 1.1
import QtQml.Models 2.3
Window {
id: mainroot
visible: true
width: 640
height: 480
Rectangle{
id:viewContainer
anchors.fill: parent
DelegateModel {
id: visualModel
model: ListModel{
id:m_model
ListElement{
type:1
m_text :"Text1"
}
ListElement{
type:1
m_text :"Text2"
}
}
delegate: Loader{
id:idLoader
width: view.width
height: childrenRect.height
Component.onCompleted: {
switch(type){
case 1:
idLoader.setSource("TestDelegate.qml", {"m_text": m_text})
break;
}
}
}
}
ListView{
id: view
anchors.fill: parent
spacing: 5
model: visualModel
}
}
}
TestDelegate.qml:
import QtQuick 2.7
MouseArea {
id: dragArea
property bool held: false
property string m_text
anchors { left: parent.left; right: parent.right }
height: 50
width: view.width
drag.target: held ? content : undefined
drag.axis: Drag.YAxis
onPressAndHold: held = true
onReleased: held = false
Rectangle {
id: content
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
width: dragArea.width
height: textfield.implicitHeight
Drag.active: dragArea.held
Drag.source: dragArea
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
border.width: 1
border.color: "lightsteelblue"
color: dragArea.held ? "lightsteelblue" : "white"
Behavior on color { ColorAnimation { duration: 100 } }
radius: 2
states: State {
when: dragArea.held
ParentChange { target: content; parent: viewContainer }
AnchorChanges {
target: content
anchors { horizontalCenter: undefined; verticalCenter: undefined }
}
}
Text{
id: textfield
anchors.centerIn: parent
text: m_text
}
}
DropArea {
anchors { fill: parent; margins: 10 }
onEntered: {
visualModel.items.move(
idLoader.item.drag.source.DelegateModel.itemsIndex,
idLoader.item.dragArea.DelegateModel.itemsIndex)
}
}
}
The items defined in the file loaded with Loader or in general with any other .qml file that is imported should not depend directly on the main file since the ids have a scope, it is better to expose properties, in your case:
╭------------------------------------------╮
| bool held ------┿--->
| TestDelegate string m_text ------┿--->
| ============ DelegateModel md ------┿--->
| int index ------┿--->
╰------------------------------------------╯
Considering the above, the solution is the following:
main.qml
import QtQuick 2.7
import QtQuick.Window 2.0
import QtQml.Models 2.3
Window {
id: mainroot
visible: true
width: 640
height: 480
Rectangle{
id:viewContainer
anchors.fill: parent
DelegateModel {
id: visualModel
model: ListModel{
id:m_model
Component.onCompleted: {
for(var i=0; i< 40; i++){
m_model.append({"type": 1, "m_text": "Text" + i})
}
}
}
delegate:
Loader{
id: idLoader
width: view.width
height: childrenRect.height
property int index: DelegateModel.itemsIndex
onIndexChanged: if(status == Loader.Ready) idLoader.item.index = index
Component.onCompleted: {
switch(type){
case 1:
idLoader.setSource("TestDelegate.qml", {
"m_text": m_text,
"index": index,
"md": visualModel
})
break;
}
}
}
}
ListView{
id: view
anchors.fill: parent
spacing: 5
model: visualModel
}
}
}
TestDelegate.qml
import QtQuick 2.7
import QtQml.Models 2.3
MouseArea {
id: dragArea
property bool held: false
property string m_text
property DelegateModel md: null
property int index : -1;
anchors { left: parent.left; right: parent.right }
height: 50
width: view.width
drag.target: held ? content : undefined
drag.axis: Drag.YAxis
onPressAndHold: held = true
onReleased: held = false
Rectangle {
id: content
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
width: dragArea.width
height: textfield.implicitHeight
Drag.active: dragArea.held
Drag.source: dragArea
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
border.width: 1
border.color: "lightsteelblue"
color: dragArea.held ? "lightsteelblue" : "white"
Behavior on color { ColorAnimation { duration: 100 } }
radius: 2
states: State {
when: dragArea.held
ParentChange { target: content; parent: viewContainer }
AnchorChanges {
target: content
anchors { horizontalCenter: undefined; verticalCenter: undefined }
}
}
Text{
id: textfield
anchors.centerIn: parent
text: m_text
}
}
DropArea {
anchors { fill: parent; margins: 10 }
onEntered: {
if(md !== null)
md.items.move(drag.source.index, dragArea.index)
}
}
}

QML ListView, SwipeView etc. - avoid overlapping of other UI components

I'm trying to avoid this annoying overlapping that both SideView and ListView seem to fancy. Here is an example which demonstrates the issue:
Note: Look at the green rectangle on the left when you swipe the SwipeView and also the tabs when you scroll down the ListView
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Window 2.0
import QtQuick.Controls 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.2
Window {
id: window
visible: true
width: 600
height: 480
title: "Demo"
RowLayout {
id: layoutTopLevel
anchors.fill: parent
spacing: 0
Rectangle {
id: sidebarView
Layout.preferredWidth: layoutTopLevel.width * .3
Layout.fillHeight: true
color: "#453"
border.width: 1
}
ColumnLayout {
id: sideViewLayout
spacing: 0
SwipeView {
id: sideView
currentIndex: sideViewPageIndicator.currentIndex
Layout.fillWidth: true
Layout.preferredHeight: layoutTopLevel.height * .9
Page {
id: page1
header: Text {
text: "Page 1"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
}
Page {
id: page2
header: Text {
text: "Page 2"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
TabView {
id: page2TabView
width: parent.width
height: parent.height
anchors.margins: 4
tabPosition: Qt.BottomEdge
Tab {
title: qsTr("Tab 1")
}
Tab {
title: qsTr("Tab 2")
ColumnLayout {
Text {
text: "Text 1"
Layout.alignment: Qt.AlignCenter
}
Text {
text: "Text 2"
Layout.alignment: Qt.AlignCenter
}
ListView {
width: parent.width
height: parent.height
model: ListModel {
ListElement {
name: "Element 1"
}
ListElement {
name: "Element 2"
}
ListElement {
name: "Element 3"
}
ListElement {
name: "Element 4"
}
ListElement {
name: "Element 5"
}
ListElement {
name: "Element 6"
}
}
delegate: Text {
text: name
}
}
}
}
style: TabViewStyle {
tabsAlignment: Qt.AlignHCenter
frameOverlap: 1
tab: Rectangle {
border.width: styleData.selected
implicitWidth: Math.max(text.width + 4, 80)
implicitHeight: 20
radius: 10
Text {
id: text
anchors.centerIn: parent
text: styleData.title
color: styleData.selected ? "white" : "black"
}
color: styleData.selected ? "#654" : "white"
}
frame: Rectangle {
color: "white"
}
}
}
}
}
PageIndicator {
id: sideViewPageIndicator
count: sideView.count
interactive: true
anchors.bottom: sideView.bottom
anchors.bottomMargin: -45
anchors.horizontalCenter: parent.horizontalCenter
delegate: Rectangle {
height: 30
width: 30
antialiasing: true
color: "#654"
radius: 10
opacity: index === sideView.currentIndex ? 0.95 : pressed ? 0.7 : 0.45
Behavior on opacity {
OpacityAnimator {
duration: 100
}
}
}
}
}
}
}
Use clip: true
Which clips the content which goes out of its boundaries.
I accidentally came across an example of a ListView while looking into another problem I had and I saw the clip property there. I have completely missed it while looking into the docs of both SideView and ListView. Basically when you set it to true the view no longer covers other components and this is exactly what I want. See comment by #Mitch on why this is not enabled by default.

Resources