Custom QML Module in the Designer - qt

Since 1 week I try to create a dynamic library which content my qml in resource file. in qmldir I declare my qml files with qrc path for not distribute my qml files to the client.
:
So when I use qrc path in my qmldir, I cannot use the auto-complementation for access to my component and I cannot access to my component form the Designer ...
But when I deploy my application my dll work fine
When I use the relative path, so without qrc://, the auto-complementation working but I cannot access to my component form the Designer ...
And when i deploy my application I NEED to deploy my qml file also of my component library
I the both case I cannot access to my component from the designer.
Maybe I make something wrong when I create my library or I forgot something ...
Any help will be appreciated for my issues...
1 : Can display my custom component in the Designer
2 : Access to auto-complementation without deploy qml

I don't know about designer, never ever used that, but in order to get auto-complete for your custom types, in addition to the qmldir file you must have a plugins.qmltypes file, which pretty much describes the structure of the components.
The good news is it can be auto-generated via:
qmlplugindump My.Module 1.0 /import/path > /import/path/my/module/plugins.qmltypes
From the looks of it, your custom types should appear in designer in their own respective tab when you import the appropriate module and have the necessary support files.

Related

How do I access Qt qrc folder directly Qt 5.10.1

I am developing an application in qml.
I have a folder qrc folder structure like ,
qrc:
Features
- Media
- Audio
- TV
graphics
- media_assets
- audio_assets
- tv_assets
Features contains respective qml files and graphics contains the graphics.
My issue is, after loading a qml file from the features it set as the current directly then, after that when I try to access the graphics folder I need to go back ../.../ and access the folder. It is making problems when folder structure is changed.
How can I access the graphics directly from qrc like graphics/media_assets/ from any qml files
In the older versions I could access the graphics directly by using "file://sample.png", in qt 5.10.1 it is deprecated.
Use:
qrc:///
From url QML Basic Type documentation:
When referring to files stored with the Qt Resource System from within
QML, you should use "qrc:///" instead of ":/" as QML requires URL
paths. Relative URLs resolved from within that file will use the same
protocol.

Switching between qrc and local path for qml files

As far as i know, the qml files could be loaded from local directory path or could be bundled in qrc file and loaded with qrc:/ URI. In debugging phase changing local qml files doesn't need recompilation of qrc file and linking together with main executable, which is fast procedure for try and error fine tuning. But in deploy phase, the qml files should be bundled together as qrc file and link to main C++ Qt application. This is good practice when you want have single executable file, however compiling qrc file and linking it again is time consuming for big projects. is there any way we can switch to qrc or local directory? for example in debug and release mode?
There is many qml components inside the project and all of these are created by URI's like qrc:/componenentname.qml inside another qml files.
So is there any way to interchange these two states in debug and release modes, and keeping qml files without duplicate changes?
All URLs inside QML, if not specified in full, are relative to the current file.
E.g. if a QML file has content like this
Image {
source: "images/foo.png"
}
then the full URL of the image is constructed at runtime based on the base URL of the QML file itself.
I.e. if the QML file itself is qrc://main.qml then the resulting path is qrc://images/foo.png, if the QML file itself is file:///path/to/your/project/main.qml then the resulting image source is file:///path/to/your/project/image/foo.png.
So if you keep URLs relative in your usage inside QML, you can simply switch between resource and local files when loading the primary QML file.
QUrl mainFile = localMode ? QUrl::fromLocalFile("main.qml") : QUrl("qrc://main.qml")
QQuickView view;
view.setSource(mainFile);
Sorry for the old post,
What we did to handle this is use Qts resource search path. We used PySide2 so examples are in python
try:
QDir.addSearchPath('search_path_name', 'path/to/root/resources')
engine.load('search_path_name:/main.qml')
except FileNotFoundError:
try:
import qml # compiled resources using pyside resource compiler
QDir.addSearchPath('search_path_name', ':/')
engine.load('qrc:///main.qml')
except ModuleNotFoundError:
pass
From this point on resources are loaded using QFile("search_path_name:some_file.txt") and it will load from either search path.

How do I localize a Qt qmldir plugin?

My app has a GUI written in Qt QML and we've successfully internationalized it using qsTr() and Qt .ts files. Now we're adding third-party plugin support via Qt's qmldir API. In the .qml files of the plugin, qsTr() works correctly only if the translation is already in the host application's .ts files. How can a third-party QML author add localized strings to their qmldir plugin?
I created a Translator class to organize and load translations. I have a QVariantMap that holds language name and file name, then when I create my Translator I have to provide the source directory since that is a requirement to load translations. My class also takes care of storing in QSettings last language used.
Now, to answer your question, you can always translate the exact same way as if it was a regular application, on your project file you will have to add something like this:
1 - List all your possible translations
TRANSLATIONS = \
translation_sp.ts \
translation_fr.ts
2 - Run lupdate to generate the actual translation files
lupdate project.pro
3 - Run lrelease
Translate with Linguist and create the actual translations. In this example, this step will generate translation_sp.qm and translation_fr.qm
4 - Deploy translations with your plugin
Once you have the .qm files deploy them with your plugin, ideally you could standardize the naming, maybe always using plugin_XX.qm
5 - Load plugin translation in application
To do this you will have to know the path to the translation file and the filename, so if your plugin is installed in the Qt default directories and you standardized the translation filenames this should be simple
qTranslator.load("plugin_XX.qm", "PATH_TO_TRANSLATION_FILE")
app->installTranslator(qtTranslator);
I simplified this in my class. Here are the header and source files of my Translator class, if you want to take a look.
And here's how you use it:
Translator translator(app.data(), "PATH_TO_TRANSLATION");
translator.addTranslation("SP", "plugin_XX.qm");
engine.rootContext()->setContextProperty("translator", &translator);
You can install multiple translators, so it will work for your application and your plugins. When I was writing my class I was not expecting different sources but you can modify it so that everytime you add a translation it will take a 2 letter code for the language, the filename and the path to it.
Hope this helps!

Change Qt application icons dynamically when language change event

I am currently working on a Qt app where the language can be changed dynamically.
To translate the strings, I used a QTranslator and overloaded the changeEvent method in each of my widgets, and everything is working fine on this side.
It's a different thing with the resources of the projects. Indeed Qt resources can have a lang attribute in the resource file (.qrc) of the application, but it seems that it is only loaded at the application startup, based on the user's locale which is not what I want. I would like to be able to change these icons dynamically when a LanguageChange event is fired in my code.
I could use rcc files to change the resource file, but it seems that this file will only be loaded at runtime, therefore I won't be able to access the resources in Qt Designer before running the program.
So can I use, let's say, a resource_en.qrc file in my application .pro file so I can set my icons with Qt Designer, and then use my .rcc files at runtime(resource_fr,etc...) to set the resources dynamically? But how could I unregister a .qrc file from the resources and replace it with an .rcc file (if possible)
Hope I made myself clear enough :D
Thank you :)
You can easily load application icon dynamically by using setWindowIcon method. Assuming mainWin is your QMainWindow.
if (lang == en)
mainWin.setWindowIcon(QIcon(":/Resources/icon/en-icon.png"));
else if (lang == vn)
mainWin.setWindowIcon(QIcon(":/Resources/icon/vn-icon.png"));
Hope this can help.
You can load and unload binary resources using the QResource::registerResource() and QResource::unregisterResource()
Dynamic resource loading
As long as the virtual paths inside each resource file is the same, they should be loaded correctly.
Have you can tried to modify your locale using QLocale?
QLocale::setDefault(QLocale(QLocale::Basque, QLocale::Spain));

Add specific phrases from Qt framework to my application's translation files

Is there a way to add specific phrases from Qt frameworks's internal .ts files to my application's translation files? I only need to translate several phrases for QMessageBox and friends.
EDIT:
I also want to:
Bundle the phrases inside my application's .ts file
Prevent them from going obsolete after a routine lupdate
There's always an alternative to subclass QMessageBox, but I'd like to try a perfectionist solution first.
EDIT #2:
I've solved the problem the ugly way by shipping a .qm file with my application from the Qt distribution. I'll keep this question open in case somebody comes up with a more elegant solution.
EDITED:
For custom translation of internal Qt phrases you only need to do some steps:
Modify appropriate qt_lang.ts in translation folder inside Qt SDK directory. I strongly recommend you to use Qt linguist for this purpose.
Use lrelease utility on qt_lang.ts to produce .qm file.
Modify your code. You need to install generated translation file in your app by using QTranslator class.
Distribute your app with generated .qm. All .qm files must be arranged in special dir relative to your app binary. By default it is translations folder, but you can change this dir by using custom qt.conf.
So when you change app language you'll get needed (translated by you) phrases.
For example, if you want to achieve custom translation for russian friends you need to open qt_ru.ts in Qt Linguist, locate there QMessageBox context and translate all needed phrases. Then follow described above instruction.
In Qt you can load various ts files for your application, i would try not to extract the needed phrases but load the qt ts files along with your own translation

Resources