QML: How can I access the id of an Item outside of repeater? - repeater

I'm new to QML and I encounter a problem when I try to access an element from inside a repeater.
I have a repeater which generates rectangles with a mouse area each. Clicking the mouse-area should change the color of the background window root defined before, but when clicked I only get: "ReferenceError: root is not defined". If I create a rectangle with mouse-area outside of the repeater then it works. So how can I access elements outside of the repeater with a mouse-area inside the repeater? Thank you for any help. I'm really stuck with this problem right now.
import QtQuick 2.0
import QtQuick.Window 2.1
Window
id: root
visible: true
width: 600; height: 600
color: "black"
{
Grid
{
columns: 3
spacing: 20
x: 20
y: 20
Repeater{
id: repeater1
model: 3
Rectangle {
color: "White"; width: 100; height: 100;
radius: 10
MouseArea
{
anchors.fill: parent
onClicked:
{
root.color="white"
}
}
}
}
}
}

I tested your code on my windows emulator, And I couldn't even run it right; it just showed me a white blank page. Maybe it's because I am not using QQuickWindow in my main.cpp.
To run it on my emulator, I changed your Window element to Rectangle and it perfectly works fine. When I click a button, the background color gets changed to white.

First import these two headers
import QtQuick 2.0
import QtQuick.Window 2.1
Second where is the curly braces {} of your window item root

Related

Qt: Qt 6.1.1 Failed to create vertex shader: Error 0x80070057

Guys!
I'm a new user of qt and I faced a problem with qml. This issue has already been discussed in this article, but for python. I write in C ++/Qt 6.1.1, QtCreator 4.15.1 for open source. Help me please.
Here is the crux of the problem: qml does not work, Application output writes the following message: "Failed to create vertex shader: Error 0x80070057: ???????? ????? ???????. Failed to build graphics pipeline state ".
The Qt documentation says that this is because of "Scene Graph Adaptations". Here is the link: https://doc-snapshots.qt.io/qt6-dev/qtquick-visualcanvas-adaptations.html.
I tried to use this method from the article in main:
QQuickWindow :: setSceneGraphBackend ("QT_QUICK_BACKEND");
For it, you also need to include the library QQuickWindow.
However, Qt gives the following error: Could not create scene graph context for backend 'QT_QUICK_BACKEND' - check that plugins are installed correctly in C: /Qt/6.1.1/mingw81_64/plugins
Here I no longer understand what to do ...
I provide the code for clarity. Since in qml it is enough to create a window and include the Rectangle {} in it.
I took the code from the example (tried 3 QtQuick examples).
Here is the main function code:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
int main(int argc, char *argv[])
{
QQuickWindow::setSceneGraphBackend("QT_QUICK_BACKEND");
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl("qrc:/sidepanel.qml"));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
QML code:
import QtQuick
import QtQuick.Controls
ApplicationWindow {
id: window
width: 360
height: 520
visible: true
title: qsTr("Side Panel")
//! [orientation]
readonly property bool inPortrait: window.width < window.height
//! [orientation]
ToolBar {
id: overlayHeader
z: 1
width: parent.width
parent: Overlay.overlay
Label {
id: label
anchors.centerIn: parent
text: "Qt Quick Controls"
}
}
Drawer {
id: drawer
y: overlayHeader.height
width: window.width / 2
height: window.height - overlayHeader.height
modal: inPortrait
interactive: inPortrait
position: inPortrait ? 0 : 1
visible: !inPortrait
ListView {
id: listView
anchors.fill: parent
headerPositioning: ListView.OverlayHeader
header: Pane {
id: header
z: 2
width: parent.width
contentHeight: logo.height
Image {
id: logo
width: parent.width
source: "images/qt-logo.png"
fillMode: implicitWidth > width ? Image.PreserveAspectFit : Image.Pad
}
MenuSeparator {
parent: header
width: parent.width
anchors.verticalCenter: parent.bottom
visible: !listView.atYBeginning
}
}
footer: ItemDelegate {
id: footer
text: qsTr("Footer")
width: parent.width
MenuSeparator {
parent: footer
width: parent.width
anchors.verticalCenter: parent.top
}
}
model: 10
delegate: ItemDelegate {
text: qsTr("Title %1").arg(index + 1)
width: listView.width
}
ScrollIndicator.vertical: ScrollIndicator { }
}
}
Flickable {
id: flickable
anchors.fill: parent
anchors.topMargin: overlayHeader.height
anchors.leftMargin: !inPortrait ? drawer.width : undefined
topMargin: 20
bottomMargin: 20
contentHeight: column.height
Column {
id: column
spacing: 20
anchors.margins: 20
anchors.left: parent.left
anchors.right: parent.right
Label {
font.pixelSize: 22
width: parent.width
elide: Label.ElideRight
horizontalAlignment: Qt.AlignHCenter
text: qsTr("Side Panel Example")
}
Label {
width: parent.width
wrapMode: Label.WordWrap
text: qsTr("This example demonstrates how Drawer can be used as a non-closable persistent side panel.\n\n" +
"When the application is in portrait mode, the drawer is an interactive side panel that can " +
"be swiped open from the left edge. When the application is in landscape mode, the drawer " +
"and the content are laid out side by side.\n\nThe application is currently in %1 mode.").arg(inPortrait ? qsTr("portrait") : qsTr("landscape"))
}
}
ScrollIndicator.vertical: ScrollIndicator { }
}
}
I have just switched from Qt 5.12 to Qt 6.1.2 and also experiencing the same problem as yours.
I'm on :
Windows x64 (with quite old CPU and so does the graphics)
Qt 6.1.2 , targeting desktop for both MSVC and MingW
In the nutshell , the working solution is to set the Qt Quick rendering to software.
But how to do it?
Nah, you just got to choose one based on your scenario:
Solution 1: Set the rendering to software permanently at OS env level
pros: you don't have to set the env value every time you create the project.
cons: this will less portable and if you move your project to another machine you might to set it again at the OS Env level.
So, this method works best for development purpose only.
How to do it?
Simply set QT_QUICK_BACKEND to software at the system env.
On Windows:
hit Win+R and type control sysdm.cpl,,3
on Environment Variables>System Variables register New... variable named QT_QUICK_BACKEND with value software
Restart Qt creator and rebuild. This should make it work without any code modification.
Solution 2: Set the QT_QUICK_BACKEND value on the fly to software
this just the same as solution 1 , but instead of writing to OS Env we just set it on the fly the flag from the code.
This method can be used either for production or development.
How to do it?
On your main.cpp simply put qputenv("QT_QUICK_BACKEND","software"); right after the main() declaration.
save and rebuild the project
Done
Solution 3: Explicitly set scene graph renderer to software
Well I see your code and that's bit miss. Instead of setting the value to QT_QUICK_BACKEND you should set to software instead.
How to do it?
on your main.cpp do importing QQuickWindow:
#include <QQuickWindow>
next, just after the main() declaration add:
QQuickWindow::setSceneGraphBackend("software");
save and rebuild project
DONE
it should works now , the window no longer show blank canvas, the QtQuick widgets are showing :
If the software renderer is not a solution, for me in the case of QtQuick3D, setting QSG_RHI_PREFER_SOFTWARE_RENDERER=1 or QT_D3D_ADAPTER_INDEX=1 as environment variables solved the issue.
See also Quick3D fails with software render backend.

is this a Qt qml bug for flags in Task Manager?

My application always run in background process, I take a long time to check why this occurs, because I think once my application runs, it should shows in Apps in task manager.
here is my test code:
import QtQuick 2.6 import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
color: "red"
title: qsTr("Hello World")
flags: Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint }
Finally I find if I remove the
flags: Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint
The app runs in Apps, but I can't set my app frameless and always on top. What can I do if I want to run my app in Apps in Task Manager?
To get your application to show up as app, you need to have a window, that is not frameless. So your problem is easily to solve, by adding another window, that is not frameless, additionally to your frameless one:
Window {
visible: true // No flags, but visible: Makes it appear as 'app'
opacity: 0 // Makes the annoying popup at the beginning invisible
Window {
id: root
width: 640
height: 480
visible: true
flags: Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint
color: 'black'
Row {
anchors.centerIn: parent
spacing: 2
Button {
text: 'flags'
onClicked: console.log(root.flags.toString(2))
}
Button {
text: 'close'
onClicked: Qt.quit()
}
}
}
}

A frameless window in QML is not updated automatically

If the window to set the flag Qt.FramelessWindowHint it stops updating automatically.
Video https://youtu.be/9LJyJWr1m9M
Please help solve the problem.
UPD:
My system: linux x64
The project for the sample http://rghost.ru/69VBkk2sr In the project, you can uncomment the line with Qt.FramelessWindowHint and color of the screen may be changed by pressing.
Example code:
import QtQuick 2.3
import QtQuick.Controls 1.2
ApplicationWindow {
visible: true
// Try comment and uncomment next line
flags: Qt.FramelessWindowHint
width: 640
height: 480
color: marea.pressed ? "lightblue" : "orange"
MouseArea {
id: marea
anchors.fill: parent
}
}

Qt Maps (QML) application window is blank

This is my code for a Qt Maps application I'm trying to make.
http://pastebin.com/PNcYivM9 - main.qml
I'm using Qt Creator on Ubuntu 14.04.
When I do compile and run the code the application window is blank.
I haven't edited the main.ui.qml apart from adding the Qt Location import.
I've also added the location keyword in the .pro file
Any help would be appreciated since I can't really find any tutorials on maps.
EDIT:
Here's the code
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtLocation 5.4
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
Plugin{
id: osmplugin
name:"osm"
}
Map {
plugin: osmplugin
id: map
zoomLevel: (maximumZoomLevel - minimumZoomLevel)/2
// center {
// latitude: -27.5796
// longitude: 153.1003
// }
// Enable pinch gestures to zoom in and out
gesture.flickDeceleration: 3000
gesture.enabled: true
// center {
// latitude: -27.5796
// longitude: 153.1003
// }
}
}
Your Map has no dimensions set, so it's going to default to a width and height of zero. To see that this is the case, add the following to your Map component:
Component.onCompleted: {
console.log("Dimensions: ", width, height)
}
This will print out:
Dimensions: 0 0
So you either need to set the dimensions to a value other than zero, or use the anchor property to attach the dimensions to the parent's anchors.

Which data model would you use to make 2 dimensional field 100*100 in QML?

The task is to create in QML field for the game snake 100*100 cells.
data model should be made with Qt C++. What is more suitable QAbstractListModel or QAbstractItemModel or QAbstractTableModel? I am trying to use a Row with many Column components in QML to create a field 100*100. It looks as a wrong approach. How else is it possible to create field 100*100 in QML and connect it with a model in C++?
I am a fresh guy in QtQuick, googling did not help.
Even if QAbstractTableModel is able to hold two dimensional data, but there is no simple way to display it in QML (GridView and TableView use only 1D model like ListModel).
I think you should try create your own TilesView and TilesModel, for your own purpose.
IMHO any advice on this topic is good for some tutorial, and I would love to link to one.
Two options come to mind here. You could use a Repeater and manually the position the items yourself according to their index:
import QtQuick 2.3
import QtQuick.Window 2.0
Window {
width: 100 * 10
height: 100 * 10
visible: true
Repeater {
model: 100 * 100
Rectangle {
x: index % 100 * width
y: Math.floor(index / 100) * height
width: 10
height: 10
border.color: "red"
}
}
}
Or you could use GridView:
import QtQuick 2.3
import QtQuick.Window 2.0
Window {
width: 100 * 10
height: 100 * 10
visible: true
GridView {
id: grid
anchors.fill: parent
cellWidth: 10
cellHeight: 10
model: 100 * 100
delegate: Rectangle {
width: grid.cellWidth
height: grid.cellHeight
border.color: "red"
}
}
}
Repeater seems to render slightly quicker.
The more suitable model (though I still think this is not the intended use of models) I'd say would be a simple model like QAbstractItemModel or QAbstractListModel.