[Solved] UI resources: RCC vs UIC and internationalization



  • There are (at last) two ways to compile UI resources into a project:

    • Use UIC to compile the UI files to header files and include them
    • Store the UI files in a QRC File and compile them with RCC to a CPP file and compile it

    I was now wondering what the advantages/disadvantages of the two methods are and if there also is a (reasonable) way to internationalize the UI files when compiling them using RCC.



  • UIC creates a Widget layout with sub widgets etc. This is normally used as private member or base of you main widget classes. With rcc you compile resources (images, files, ..) into you project so you can use them directly inside you binary without accessing the hard disk.

    The uic is the "User Interface compiler":http://doc.trolltech.com/4.7/uic.html
    The user interfaces you compile wit uic are created by the "QtDesigner":http://doc.trolltech.com/4.7/designer-manual.html
    The rcc is the "Resource Compiler":http://doc.trolltech.com/4.7/rcc.html



  • @Gerolf: Thank you for your feedback!

    This all makes sense but I can also compile UI files using RCC (is this actually documented somewhere?) and can use them to create widgets with sub widgets in a Qt app.

    I understand the basic architectural differences between the two approaches, but what I was wondering (and did not find any information in the documents you mentioned) is why this is possible and what advantages/disadvantages it would have to go this path.

    The only think that seems not to be possible with RCC compiled UI's (at least out of the box) is the use of the internationalization tools that take advantage of the standard translation options in Qt.



  • Why do you use rcc to compile ui files? I never tried that and I don'T think that it is, how the Trolls want the tools be used. perhaps, the internals use some shared logic so it is (partly) possible. But the normal way is always: UIC for ui files, rcc for qrc files. That's also what qmake and does.



  • I'm not actually using them in a production environment but rather trying to find out what best suites my needs and I discovered this option just by mistake.
    The fact that it is supported by RCC would suggest to me that this can be useful and so I would like to better understand.



  • I would suggest using qmake, then you are on the save path. Qmake uses the correct tools.



  • Time to clean up some meanings:

    You can use a .qrc file to story any arbitrary data in a file in your application. You call rcc on that .qrc file, which in turn generates a .cpp file, which is just compiled an linked to your application. The .cpp basically converts the files' contents into an array of bytes:

    @
    static const unsigned char qt_resource_data[] = { ... a bunch of bytes };
    @

    You then can access the files in the resources in the same way as if they were on the file system, but you need not copy the files themselves to the computers where you install your application.

    On usually puts images, icons, sound files, static text, etc. into the resource.

    Qt Designer generated user interfaces (.ui files), are generally processed with uic. This generates a ui_xxxx.h file for you, that contains some C++ code to set up your ui in your application. The "Using a Designer UI File in Your Application":http://doc.qt.nokia.com/latest/designer-using-a-ui-file.html chapter of the "Qt Designer Manual":http://doc.qt.nokia.com/latest/designer-manual.html shows you the details.

    This is the only way to compile the user interface into your application.

    You can store the .ui file in a .qrc file, but that is not meant as "compiled in". You must use "QUiLoader":http://doc.qt.nokia.com/latest/quiloader.html to show the user interface in this case. It could also be stored on the file system or downloaded from some server. This is not recommended for the beginners and, in my opinion, it is only useful if you have dynamic user interfaces, that can change after you delivered your application. I strongly advice against this in your case.

    [edit: added this about internationalization]
    To answer your translation question: In Qt world mostly "Qt Linguist":http://doc.trolltech.com/latest/linguist-manager.html is used to make the translations. It works on the header, source and UI-Files (.h, .cpp, .ui) of your project. It does not matter if you put your .ui file an rcc file, as it works on the source on your disk. Qt resources are often used to make translations available in the application. You load them with the ":/" prefix and use them as if they were on the disk.



  • I understood it that way, that he used rcc to compile ui files, not to put them in a qrc file. Was this a misunderstanding?



  • You cannot "compile" uic files with rcc (in the sense most Qt users use it), but only with uic.

    rcc takes an XML based configuration file (the .qrc). The configuration file points to the actual files on the disk. rcc generates a C++ source file and puts into it the contents of all the files from configuration .qrc in a way so that the C++ compiler can generate a bunch of bytes. If you access that data structur from your application, you get back the original bunch of bytes you once had on the disk. This might be your .ui file. You then only have the XML based .ui file, that Qt Creator saved. You do not have C++ compilable header file!

    uic on the other hand takes only one .ui file and generates a C++ header file (ui_xxx.h) that contains code to create actual widgets, layouts, etc. You add that to your project and save you the task of creating the user interface manually.

    Both tools generate a source file and both files can (and shall!) of course be compiled with the C++ compiler. But the difference is, that uic actually transforms the ui file and the ui_xxx.h contains generated code. You cannot retrieve the original .ui file out of the ui_xxx.h. rcc on the other hand, only kind of packs the file and you get back the original file.

    BTW: You cannot use rcc on a file without putting the file into the .qrc config file.



  • I thought it is that way, but never tried. And I understood, he did that way. If that was wrong, sorry... but that can happen :-)
    Otherwise I agree, don't put ui files in a resource, use it directly. It makes more sense, especially, as you can implement classes based on that and connect directly.



  • Yepp, that's much more easier to use. QUiLoader can also be used on the plain .ui XML, but that's left for the advanced Qt coders and should only be used if you really need that functionality.



  • Thank you for the very detailed and analytic explanation! It made me better understand what I'm looking for.
    In my specific use case I will most likely need both options:

    1. Loading resources that have been compiled with RCC from a QRC file dynamically with QUiLoader for Ui resources that need to be "changed" a runtime before actually showing them.
    2. Using the header files generated from the UI files using UIC for "static" resources.

    What's also crystal clear now is my seconds question related to the internationalization of dynamic UI resources. This is something that needs to be done "manually" when loading the resources and cannot be supported by the standart Qt i18n support.



  • But be aware, that the resources from the qrc file are compiled into your application and therefore are static too! qrc/rcc is no means to add changed or dynamically created resources to your application after you have compiled it!

    It depends on what the changes to your UI are in order to decide if you'd better go with ui files or do the changes programmatically. Even if you created your UI with Designer and made a ui_xxx.h with uic from it, you can change the user interface afterwards by adding some more widgets or even delete widgets that were created before. If you wrap all your user visible strings into tr() you can translate these modifications too.

    The approach using QUiLoader seems to be a good way, if you have the UI files ready-to-use, for example, on a server and download it before your application shows it. If you do that, you can also add the matching translation files (.qm ending, created with Qt Linguist and lrelease) and load them into your app.



  • [quote author="Volker" date="1292578883"]But be aware, that the resources from the qrc file are compiled into your application and therefore are static too! qrc/rcc is no means to add changed or dynamically created resources to your application after you have compiled it![/quote]I understand.

    [quote author="Volker" date="1292578883"]It depends on what the changes to your UI are in order to decide if you'd better go with ui files or do the changes programmatically. Even if you created your UI with Designer and made a ui_xxx.h with uic from it, you can change the user interface afterwards by adding some more widgets or even delete widgets that were created before. If you wrap all your user visible strings into tr() you can translate these modifications too.[/quote]Thank you for the clarification. My specific use case emulates a legacy toolkit. I have to load the UI resources to get the information about the resources but will actually create a completely different object hierarchy.

    [quote author="Volker" date="1292578883"]The approach using QUiLoader seems to be a good way, if you have the UI files ready-to-use, for example, on a server and download it before your application shows it. If you do that, you can also add the matching translation files (.qm ending, created with Qt Linguist and lrelease) and load them into your app.[/quote]Does this mean, that it is also possible to use Qt Linguist and lrelease when loading resources via QUILoader? This is exactly what I'm very interested in but can't figure out how to do. Could you shortly explain how this would work or point me to an example or to the proper documentation.



  • You can call lupdate on a list of .ui files to generate the linguist source files (.ts):

    @
    lupdate mainwindow.ui dialog.ui -ts bla.ts
    @

    This takes the Qt Designer form files mainwindow.ui and dialog.ui, extracts all the translatable strings (labels, buttons, etc.) and puts it into bla.ts, which in turn can be translated using Qt Linguist. When you're done, call

    @
    lrelease bla.ts -qm bla.qm
    @

    To generate the final translation file bla.qm out of the bla.ts. You then can deliver the .ts file together with your .ui file. You should first load the translation file and then instantiate the widget from the QUiLoader.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.