The following project structure is working for import a qml module:
Project structure
Project
|- modules
|- Goofy
|- qmldir
|- Donald.qml
|- project.pro
|- main.cpp
|- main.qml
|- qml.qrc
project.pro
QT += quick
SOURCES += \
main.cpp
RESOURCES += \
modules/Goofy/Donald.qml \
modules/Goofy/qmldir \
qml.qrc
QML_IMPORT_PATH = $$PWD/modules
QML_DESIGNER_IMPORT_PATH = $$PWD/modules
main.cpp
QQmlApplicationEngine engine;
engine.addImportPath("qrc:/modules");
main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import Goofy 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Donald{}
}
qmldir
module Goofy
Donald 1.0 Donald.qml
How should I modify my project to import the module from a qrc file instead of adding any single file to the resources??
Ideally I'd like to have the following pro file:
project.pro
QT += quick
SOURCES += \
main.cpp
RESOURCES += \
modules/Goofy/goofy.qrc \
qml.qrc
QML_IMPORT_PATH = $$PWD/modules
QML_DESIGNER_IMPORT_PATH = $$PWD/modules
I tried adding goofy.qrc (or Goofy.qrc) to my modules/Goofy folder with the following format:
<RCC>
<qresource prefix="/">
<file>qmldir</file>
<file>Donald.qml</file>
</qresource>
</RCC>
but it doesn't work. What should I do?
Your Goofy.rcc doesn't work because the files are not located in the used importPath. The files are next to the qrc, so no relative path is added to the specified prefix. Alter the rcc to the following to make it work:
<RCC>
<qresource prefix="/modules/Goofy">
<file>qmldir</file>
<file>Donald.qml</file>
</qresource>
</RCC>
As you already seem to understand, the qmldir file needs to be in the Goofy path for the QmlEngine to accept it. Add that to the specified import path and QmlEngine will find your module, just like it's on disk (since qrc is actually rendered as a normal filesystem)
BTW, You can check the working of relative qrc paths with the following snippet:
QDirIterator qrc(":", QDirIterator::Subdirectories);
while(qrc.hasNext())
{
qDebug() << qrc.next();
}
Related
A QML FileDialog to save a file works fine in debug mode.
The code is:
import QtQuick 2.5
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Dialogs 1.2
import Qt.labs.settings 1.1
import QtQuick.Controls.Styles 1.4
import Qt.labs.platform 1.0
Item {
property string exportSceneName: "exported_scene"
property url exportFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
signal startExport()
onStartExport: {
runLogic()
}
function runLogic() {
// ...
}
Button {
onClicked: {
fileDialog.open()
}
}
FileDialog {
id: fileDialog
folder: exportFolder
fileMode: FileDialog.SaveFile
title: qsTr("Export Scene As STL")
onAccepted: {
exportFolder = folder
var name = basename(file)
exportSceneName = name
startExport()
}
}
function basename(str) {
return (String(str).slice(String(str).lastIndexOf("/")+1))
}
}
Release mode
Surprisingly, in release mode, the dialog is open-type rather than save-type:
I have tried:
Change the QML imports versions
Clean the release build directory
Modify qtquickcontrols2.conf file
However, none of them worked! I have studied similar posts like this one, but suggestions didn't work. What else can I try? Thanks.
SOLUTION
Fixed by removing this import inside QML file:
import QtQuick.Dialogs 1.2
I'm going to guess that the issue is conflicting FileDialog definitions. Note that both imports QtQuick.Dialogs and Qt.labs.platform provide an object called FileDialog, but they do not use the same API. (There are several other objects like this in QML, and it's really annoying.) So it's probably trying to use one version of the dialog in debug mode, but for some reason choosing the other one in release mode.
The solution is to first of all make sure you remove any imports that you're not actually using. Then if you still need both, then you can label the imports:
import QtQuick.Dialogs 1.2 as QDiag
import Qt.labs.platform 1.0 as QPlat
Then when you create the FileDialog, you'll have to explicitly state which one you want to use.
QDiag.FileDialog {
}
QPlat.FileDialog {
}
I need some help on QML importing. I have 2 projects, name Project1 and Project2
Project 1
|-QmlFile1.qml
|-qml1.qrc
Project 2
|-QmlFile2.qml
|-qml2.qrc
Is it possible to import QmlFile1.qml from Project 1 to QmlFile2.qml of Project 2?
QT_WS\TestQuick\main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import "../COMMON"
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MyButton {
id: button1
}
}
QT_WS\COMMON\MyButton.qml
import QtQuick 2.0
Item {
width: 400
height: 80
Rectangle {
id: button
anchors.fill: parent
color: "red"
}
}
QT_WS\TestQuick\TestQuick.pro
QT += quick
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp
RESOURCES += qml.qrc \
sharedresource.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
main.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
sharedresource.qrc
<RCC>
<qresource prefix="/">
<file>../COMMON/MyButton.qml</file>
</qresource>
</RCC>
Error:
Starting C:\Personal\QT_WS\build-TestQuick-Desktop_Qt_5_9_4_MSVC2015_64bit-Debug\debug\TestQuick.exe...
QML debugging is enabled. Only use this in a safe environment.
QQmlApplicationEngine failed to load component
qrc:/main.qml:3 "../COMMON": no such directory
C:/Personal/QT_WS/build-TestQuick-Desktop_Qt_5_9_4_MSVC2015_64bit-Debug/debug/TestQuick.exe exited with code -1
Folder structure screenshot
I think what you're probably missing is the qml file is not in your .qrc file so it doesn't know where to find it. If you're going to be sharing code between projects, it makes sense to create a separate .qrc file for common files that will be included in both. So your project structure could look like this:
Project 1
|---qml1.qrc // Files for Project1
|---someFile1.qml
|---shared_qml.qrc // Shared files
|---sharedFile1.qml
|---sharedFile2.qml
Project 2
|---qml2.qrc // Files for Project2
|---someFile2.qml
|---shared_qml.qrc // Shared files
|---sharedFile1.qml
|---sharedFile2.qml
EDIT:
I tried building a project with the same structure you used. It worked when I imported the file like this:
import "qrc:/../COMMON"
It is tricky to share code in the way you are trying to do it now, as the qrc system does not support pointing to paths outside the project tree.
Instead, I would suggest you factor out the shared code into a library that you then use from both projects. That will probably be easier to maintain in the long run anyway.
I want to import my custom QML type MyType from subdirectory mytypes into my main.qml file. Which is also in the same directory with the mytypes folder. I used this documentation page as reference.
http://doc.qt.io/qt-5/qtqml-syntax-directoryimports.html
I use it as follows:
import "mytypes"
MyType {
}
In code, MyType is recognized and highlighted as usual. However, when I run the application, I get the following error:
qrc:/main.qml:5:1: "mytypes": no such directory
And my .qrc file looks like that:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
<qresource prefix="/mytypes">
<file>mytypes/MyType.qml</file>
</qresource>
</RCC>
So where is the error? Should I also make some changes in the .pro file?
The qrc file
<qresource prefix="/mytypes">
<file>mytypes/MyType.qml</file>
</qresource>
says mytypes/MyType.qml is under the prefix /mytypes. Therefore, the import statement in main.qml should include that prefix:
import "mytypes/mytypes"
MyType { }
Or, remove /mytypes prefix and move mytypes/MyType.qml under / prefix in qrc file:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>mytypes/MyType.qml</file>
</qresource>
</RCC>
and main.qml can import the type directly:
import "mytypes"
MyType { }
Situation:
Writing a Qt Quick application for embedded Linux system, want to use Qt translation mechnanism. Application shall select language on command coming in via RS232, currently hardcoded to "de" on a system set up for english language. Application loads various masks on command from RS232.
Problem:
Qt Quick translates only the main page (main.qml), but not the pages loaded via the Qt Loader (DEMO.ui.qml). Texts from main.qml are displayed in german, texts from DEMO.ui.qml are displayed untranslated.
I've added a "XX" prefix to all english translations (qml.en.ts), that also does not appear on the screen. So neither english nor german translations are loaded for pages loaded via the Qt Loader.
Clean build after lupdate, lrelease does not help. rm -rf build-$appname-*, build does not help.
Code:
application.cpp:
xlat=new QTranslator();
if (xlat->load(QLocale("de"), "qml", ".", ":/qml/i18n/", ".qm")) {
qDebug()<<"load translator ok";
bool ok=installTranslator(xlat);
//...
} // else error message
// ...
viewer->setSource(QUrl("qrc:/qml/main.qml"));
viewer->showFullScreen();
// ...
main.qml:
import QtQuick 2.0
Rectangle {
Text {
id: loadingMsg
text: qsTr("Loading ...")
// ...
}
Loader {
// ...
source: ""
function loadMask(aMaskId) {
// ...
setSource(gui.urlForMask(aMaskId));
}
}
// ...
}
components/SimpleButton.qml:
import QtQuick 2.0
// ...
Rectangle {
Text {
id: label
text: ""
// ...
}
property alias text: label.text
}
masks/DEMO.ui.qml:
import QtQuick 2.0
import "../components"
//...
SimpleButton {
//...
text: qsTr("Vent.")
}
//...
qml.de.ts:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
<!-- ... -->
<context>
<name>DEMO</name>
<!-- ... --->
<message>
<source>Vent.</source>
<translation>Belüften</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<source>Loading ...</source>
<translation>Lade ...</translation>
</message>
<!-- ... -->
</context>
Renaming DEMO.ui.qml to DEMO.qml did the trick. I guess that the Linguist tools (lupdate, lrelease) and the Qt runtime environment have different ideas of how to convert a filename to a context name.
I'm trying to use the QML-material library in a Qt Quick Application.
But when I try to use the import code it says
module "Material" is not installed`
import Material 0.1
I did also try this but that seems not to work:
import "modules/Material" as Material
qml.qrc looks like this, all qmldir files are listed:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>modules/Material/qmldir</file>
<file>modules/Material/Extras/qmldir</file>
<file>modules/Material/ListItems/qmldir</file>
<file>modules/QtQuick/Controls/Styles/Material/qmldir</file>
</qresource>
</RCC>
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.addImportPath("qrc:/");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
Is there something I'm missing or is it not possible to use qmldir in qrc file?
You need to add to the import path the folder where the modules are located.
In this case it's qrc:/modules/.
Example:
engine.addImportPath( "qrc:///modules" );
For a module to work you need to have access to the qmldir file, but also all the files referenced in it. So you need to add all the files of the library to the the qrc.