Qt QML Settings are not saved/applied - qt

I have simply copied this example from the docs, adjusting the import version number to the newest ones (but I tried with both for same result).
import QtQuick.Window 2.12
import Qt.labs.settings 1.1
Window {
id: window
width: 800
height: 600
Settings {
property alias x: window.x
property alias y: window.y
property alias width: window.width
property alias height: window.height
}
}
As opposed to advertised, the window geometry was not saved after I closed and reopened the window. In fact, it now doesn't show the window at all? (I tried re-running qmake and cleaning all)
I also get this warning every time I run the project in Qt Creator, regardless of whether I use Settings or not:
17:01:02: Starting C:...debug\untitled.exe...
QML debugging is enabled. Only use this in a safe environment.
qrc:/main.qml:10:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
qrc:/main.qml:10:5: QML Settings: The following application identifiers have not been set: QVector("organizationName", "organizationDomain")
1) Is the warning related to the issue?
2) How do I remove the warning?
3) How do I get the settings to be applied as advertised?

...Turns out I had to keep reading the docs to the end.
1) Warning is related to the issue.
2) Per the docs, add this at the beginning of the main in main.cpp
app.setOrganizationName("Some Company");
app.setOrganizationDomain("somecompany.com");
app.setApplicationName("Amazing Application");
3) Now works as advertised.

Related

QtWayland client distorted on Raspberry Pi 4

I'm trying to create a very simple wayland compositor using the examples found here, like this:
import QtQuick 2.12
import QtQuick.Window 2.2
import QtWayland.Compositor 1.3
WaylandCompositor {
id: wlcompositor
WaylandOutput {
compositor: wlcompositor
window: Window {
width: 800
height: 480
visible: true
title: wlcompositor.socketName
Grid {
anchors.fill: parent
anchors.margins: 100
columns: 2
Repeater {
model: shellSurfaces
ShellSurfaceItem {
id: shellSurfaceItem
autoCreatePopupItems: true
shellSurface: modelData
onSurfaceDestroyed: shellSurfaces.remove(index)
}
}
}
}
}
ListModel { id: shellSurfaces }
XdgShell {
onToplevelCreated: shellSurfaces.append({shellSurface: xdgSurface})
}
}
And then I'm creating a separate client app that just creates a couple Rectangles as a test.
import QtQuick 2.12
import QtQuick.Window 2.12
Window
{
id: window
visible: true
width: 200
height: 200
Rectangle
{
anchors.fill: parent
color: "green"
Rectangle
{
x: 10
y: 10
width: 100
height: 100
color: "blue"
}
}
}
Everything seems simple and straightforward. But when I run it on my Pi4 (using the -platform wayland flags), the client gets crazy distortion, like this:
I'm testing it with Boot2Qt, which is a yocto linux image. I've tried Qt versions 5.14.2 and the newest 5.15.0 with the same results. There are no errors on the console. Nothing that indicates anything is wrong except that it looks awful.
I did notice that if I use weston as my compositor instead of QtWayland, then the app looks perfect. So that makes me think there's something wrong with WaylandCompositor. But my search of google found nobody else complaining of the same thing.
I don't even know what to try. Does anybody have any ideas?
I had similar effects using qt 5.15.1 and qt 5.15.2 with qt wayland on the pi 4. I managed to get QT Wayland working with no distortion by compiling the mesa driver 20.3.3 and 20.3.4, using the following options:
-Dplatforms=x11,wayland -Dvulkan-drivers=broadcom -Ddri-drivers= -Dgallium-drivers=kmsro,v3d,vc4 -Dbuildtype=release -Dprefix=/usr -Degl=true
After installing the drivers i updated the sysroot on my host and cross-compiled the QT Lib.
That made it finally working. Good luck.
I've encountered this very same issue from Qt 5.12 to 5.15, and Qt 6.2.0 RC.
The solution to avoid distortion is to enable dma-buf in QtWayland, and set hardware integration from the compositor side:
export QT_WAYLAND_CLIENT_BUFFER_INTEGRATION=linux-dmabuf-unstable-v1
export QT_WAYLAND_SERVER_BUFFER_INTEGRATION=dmabuf-server
Note that in order to enable dma-buf it required me to tweak .pro and configure.json files (I'm doing native build on the Pi4), as the libdrm-dev header couldn't be detected by qmake or cmake correctly.
Add INCLUDEPATH += /usr/include/libdrm/ to the following two:
./src/plugins/hardwareintegration/client/dmabuf-server/dmabuf-server.pro
./src/plugins/hardwareintegration/compositor/dmabuf-server/dmabuf-server.pro
And add libdrm/ before drm headers in following files:
./src/client/configure.json
./src/compositor/configure.json
A re-configure & rebuild should work. Tested on Pi4 + Qt 5.15.2 with both armhf and arm64 image, using dtoverlay=vc4-kms-v3d-pi4 overlay.
If memory serves me correctly, the closed-source graphics driver are a real pain when it comes to wayland support. You may have some luck by enabling the broadcom backend (which I think it's what appropriate for rpis) for qt wayland by setting QT_WAYLAND_CLIENT_BUFFER_INTEGRATION=brcm before starting the compositor.
There is some info about this env var in this readme: https://code.qt.io/cgit/qt/qtwayland.git/tree/README
But if practically possible, I would think the mesa open-source drivers will give you a lot less pain, as it's much more widely used and support is likely much better.

What is qmltestrunner?

I have gone through the documentation provided by Qt on TestCase, Qt Quick Test Reference Documentation, Ubuntu QML unit testing, Testing with qmltestrunner part 1 & 2, Writing and running qml testcases, How to create a Qt-Quick Test
All that I have found about it is:
Qmltestrunner is a tool used for unit testing. This tool allows to execute QML files as test cases. These files should contain test_functions. Qmltestrunner is an open-source project and its source code can be found from the github.
But there are few questions for which I'm looking out for answers:
qmltestrunner documentation? where can I find it? (Could not find wiki page for it)
Is qmltestrunner part of qt quick test framework?
What all dependencies are there for qmltestrunner?
Is there any proper example where I can find complete explanation about QML unit testing? qt quick test framework explains running-tests which I couldn't understand.
Thank you
Unfortunately there's no documentation for qmltestrunner (I cannot one). If you only want to know how to use it, qmltestrunner.exe -h may help you. Most options are described in Qt Test Overview.
Yes. Qt Quick Test Reference Documentation - Running Tests says you need a .cpp file that contains QUICK_TEST_MAIN(xxx) and a .pro file that contains CONFIG += qmltestcase, and build this project to run your QML unit tests. The output binary file of this project is (almost the same as) qmltestrunner.
To run qmltestrunner (in Windows with Qt 5.7, for example), you need at least the following modules: Qt5Core.dll, Qt5Gui.dll, Qt5Network.dll, Qt5Qml.dll, Qt5Quick.dll, Qt5QuickTest.dll, Qt5Test.dll, Qt5Widget.dll. And some extra modules for your QML files if needed (ex. QtQuick Controls 2)
TestCase describes how to write a unit tests in QML. To run the file, simply run qmltestrunner.exe -input C:\My\Testing\File\Path\tst_myComponentTest.qml in command line.
Here's simple step-by-step example about how to write a QML component with unit tests. For example, assume that we have a ExpandButton that expands when it is clicked:
//ExpandButton.qml
import QtQuick 2.7
import QtQuick.Controls 1.2
Button {
width: 50; height: 50
onClicked: { width = 100; }
}
To test this behavior, write a tst_ExpandButton.qml:
import QtQuick 2.7
import QtTest 1.0
Item {
width: 800; height: 600
ExpandButton {
id: expandButton
anchors.centerIn: parent
}
TestCase {
name: "ExpandButton"; when: windowShown
function test_clickToExpand() {
var widthBeforeClick = expandButton.width;
mouseClick(expandButton);
var widthAfterClick = expandButton.width;
verify(widthBeforeClick < widthAfterClick);
}
}
}
Now we have two QML files, ExpandButton.qml and tst_ExpandButton.qml. Run the unit test with qmltestrunner.exe -input D:\aaa\bbb\tst_ExpandButton.qml and you can see the result:
********* Start testing of qmltestrunner *********
Config: Using QtTest library 5.7.0, Qt 5.7.0 (i386-little_endian-ilp32 shared (dynamic) release build; by MSVC 2015)
PASS : qmltestrunner::ExpandButton::initTestCase()
PASS : qmltestrunner::ExpandButton::test_clickToExpand()
PASS : qmltestrunner::ExpandButton::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 13ms
********* Finished testing of qmltestrunner *********
http://doc.qt.io/qt-5/qtquick-qtquicktest.html This will help in understanding qmltest runner
http://doc.qt.io/qt-5/qml-qttest-signalspy.html This will help in understanding signal spy which is used to catch signals
http://doc.qt.io/qt-5/qml-qttest-testcase.html This will help in writing each test case

qml local import: either highlited, or works

I had problem when I tried to import local directory qml files( they are in the another prefix in qml.qrc)
import QtQuick 2.0
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.2
import "Components"
//import "qrc:/Components/QMLs/Components"
Rectangle {
id: mainLocalRect
width: 300
height: 500
color: "orange"
HIcon {
id: hIcon
x: 0
y: 0
}
}
So that, I got error when deploying:
qrc:/QMLs/welcome.qml:4:1: "Components": no such directory
but there is directory Components and in Qt Creator HIcon is highlighted.
https://yadi.sk/i/eF1QKfxEhsdiY
I tried another way to import:
import "qrc:/Components/QMLs/Components"
And its works! But now SideMenu is not highlighted
https://yadi.sk/i/jmdgDZ4dhsdix
Structure of files in project:
main.qml
--QMLs/
----class.qml
----welcome.qml
....
----Components/
------HIcon.qml
Question: How to correctly to import directory?
You can use simply:
import "rel_path"
Where rel_path is the relative path from the point of view of the file that contains the import statement.
As an example, if the component C is in a child directory called D for the parent one, use:
import "../D/"
From now on, you can freely use C within your file.
The reason why highlighting does not work when using the correct qrc import is that QtCreator does not inspect the qrc file.
In addition you have to know how the resource system packages the files. Every file will be packaged with it's relative path to your .qrc file:
main.qml -> qrc:///main.qml
QMLs/welcome.qml -> qrc:///QMLs/welcome.qml
When using prefixes in your resource files those will be prepended to the relative path. (It's not that Qt 'copies' that file into the specified prefix/folder)
In your project that leads to the following situation:
QMLs/Components/SideMenu.qml -> qrc:///Components/QMLs/Components/SideMenu.qml
QMLs/Components/Helpers/MenuBackIcon.qml -> qrc:///Helpers/QMLs/Components/Helpers/MenuBackIcon.qml
It's not only a change in the absolute URL. It also 'moves' the files in the position relative to each other.
Now, to make things better you can specify an alies for each file in your .qrc file. An alias can just be a file name that will be combined with the prefix to make up the full URL:
Let's say you give the alias HIcon for your file QMLs/Components/HIcon.qml. That will lead to the situation that the full URL will be: qrc:///Components/HIcon.qml
Because your .qrc file is in the list of import paths you can now write your code like you'd expect:
import "Components"
[..]
HIcon {
[..]
}
Conclusion / TL;DR
Give each file an alias that is made up of the files name without the path.

QML Object Type is not a type error in QTCreator

Hi Everyone i am new to QT and i am having trouble loading one qml through another qml
Basically i have created a qml MyTabView(MyTabView.qml)
import QtQuick 2.3
import QtQuick.Controls 1.2
TabView {
width: 360
height: 360
Component.onCompleted: {
addTab("Tab 1", tab1)
addTab("Tab 2", tab2)
}
Component {
id: tab1
Rectangle {color: "red"}
}
Component {
id: tab2
Rectangle {color: "blue"}
}
}
and i am trying to show it through another qml(main.qml) which is in the same directory
import QtQuick 2.3
import QtQuick.Controls 1.2
import "."
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Main")
MyTabView {}
}
but when i try to run my project i get this error
QQmlApplicationEngine failed to load component
qrc:/qml/main.qml:11 TabView is not a type
Please note that i have M Caps in MyTabView.qml and that MyTabView.qml and main.qml are in the same directory.
Can someone point me what mistake i am doing ?
One thing i want to point is that when i replace all the code of MyTabView.qml instead of MyTabView {} inside main.qml,the program does not give any error and runs correctly.
Thanks in advance
Have you added the file to your Resources ?
Adding your MyTabView.qml to your project in the same directory of main.qml is not sufficient.
You have to put your QML file in the Resources (probably main.qrc/qml/) in order to have it deployed.
The editor of Qt Creator does not need this inclusion in order to find your type, therefore it displays no error.
I had a similar problem.
qrc:AGview.qml:8:15: AGraph is not a type
I solved it:
my original code (in my main.cpp):
view.setSource(QUrl("qrc:AGview.qml"));
the working one:
view.setSource(QUrl("qrc:/AGview.qml"));
I think without the slash it don't search in the actual folder.
You should rename your "TabView.qml" to something like "MyTabView.qml".
Because of that import
import "."
you have conflict of TabView from "QtQuick.Controls 1.2" and local folder "."
This error can also be caused by a component's having an error. For instance, I had this sequence of errors:
QQmlApplicationEngine failed to load component
qrc:/main.qml:6 Type MainView unavailable
qrc:/MainView.qml:27 Type ApplicationLocked unavailable
qrc:/ApplicationLocked.qml:4 MetaStateChart is not a type
It's not very clear, bu the error in MainView is caused by a problem in ApplicationLocked. When I fixed that error, everything else worked.
So contrary to the conventional wisdom of starting with the first compiler error, it may be necessary to start with the last one!
I have the same thing as you, there are 2 solutions, Frist is to lower the qt version below 6, the second is to use cmake to compile, it will be successful
Ok I have had this problem recently with QT 6.2 and QML. Using both CMake and QMake as the build systems.
The solution is to add the QML file e.g. MyTabView.qml to the resources file and make sure it is added to the CMakeLists.txt or the project file (should be done automatically for you).
Then in the top of your main.qml or wherever you are using this custom component import qrc:/. Assuming the custom qml file was added under the prefix / and therefore its resource path will be qrc:/MyTabView.qml.

crash at exit when creating a QML application with Visual Studio and Qt 5.3

I've been playing with QML application and extensions through qmlRegisterType, and I stumbled into a strange thing : I have 2 projects. The first one produces a dll with a custom QML type, and the second one is a really simple application which looks like this :
main.cpp :
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine(QUrl("qrc:/main.qml"));
return app.exec();
}
main.qml
import QtQuick 2.3
import QtQuick.Window 2.2
import TestLib 1.0
Window {
visible: true
width: 360
height: 360
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
HelloWorld {
id: hello
test: "Foo !!"
}
Text {
anchors.centerIn: parent
text: hello.test
font.pointSize: 40
}
}
When I run my project through Qt Creator, everything works fine, and when I click anywhere on the window, it closes properly.
But now, if I try to compile the exact same code through a Visual Studio project (I use and special version of Premake to generate the Visual Studio solution and project files which handle the Qt special files correctly) then everything compiles, runs fine, but as soon as I click on the window, I have a crash with the following callstack :
ntdll.dll!RtlFreeHeap() Unknown
kernel32.dll!HeapFree() Unknown
msvcr120.dll!free(void * pBlock) Line 51 C
TestLib.dll!000007fef7bb6d6c() Unknown
Qt5Cored.dll!QObjectPrivate::deleteChildren() Line 1936 C++
Qt5Cored.dll!QObject::~QObject() Line 1030 C++
Qt5Quickd.dll!QQuickItem::~QQuickItem() Line 2120 C++
Qt5Quickd.dll!QQuickRootItem::~QQuickRootItem() C++
Qt5Quickd.dll!QQuickRootItem::`scalar deleting destructor'(unsigned int) C++
Qt5Quickd.dll!QQuickWindow::~QQuickWindow() Line 1102 C++
Qt5Quickd.dll!QQuickWindowQmlImpl::~QQuickWindowQmlImpl() C++
Qt5Quickd.dll!QQmlPrivate::QQmlElement<QQuickWindowQmlImpl>::~QQmlElement<QQuickWindowQmlImpl>() Line 106 C++
Qt5Quickd.dll!QQmlPrivate::QQmlElement<QQuickWindowQmlImpl>::`scalar deleting destructor'(unsigned int) C++
Qt5Qmld.dll!qDeleteAll<QList<QObject * __ptr64>::const_iterator>(QList<QObject *>::const_iterator begin, QList<QObject *>::const_iterator end) Line 323 C++
Qt5Qmld.dll!qDeleteAll<QList<QObject * __ptr64> >(const QList<QObject *> & c) Line 332 C++
Qt5Qmld.dll!QQmlApplicationEnginePrivate::cleanUp() Line 64 C++
Qt5Qmld.dll!QQmlApplicationEngine::~QQmlApplicationEngine() Line 241 C++
TestApp.exe!000000013faf2630() Unknown
TestApp.exe!000000013faf4197() Unknown
I spent a lot of time browsing Google and such, but I couldn't find anything helpfull. I think that maybe I'm missing some compilation option in my projects, that Qt Creator automatically adds, but I don't know which one :/
I know that just looking at this question will probably not be sufficient to find a solution, so I prepared a small project that perfectly reproduces the problem. If you're willing to try it, feel free to drop me a message, and I'll send it to you (I don't have any dropbox account or equivalent, unfortunately)
Thanks in advance for any help !
You are using at least part of Release CRT msvcr120.dll with your Debug application and debug Qt dlls. It is not safe to mix Debug and Release in the same application because this creates more than 1 independent heap. If you allocate memory in the release heap you can not free it in the Debug heap and vise-versa because doing so corrupts the heap. Also the heap corruption does not necessarily cause an instant crash at the next allocation / deallocation so it becomes hard to debug. As you found out using the correct CRT will fix this problem.

Resources