Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Accessing qrc resources



  • Hello, first time posting here.

    I am fairly new to the Qt world. I am working on creating a windows dll with Visual C++.

    My problem is that I cannot seem to load icons from qrc resources. If I load the images from external files, there is no problem. But no success loading the icons from the resources.

    ⦁ I have created a DrivenControler.qrc file to my vs vcxproj project
    ⦁ I added the image files to the resource file in the Qt Resource Editor and everything looks fine, resulting in resource URLs like ":/DrivenController/Images/muted.png"
    ⦁ The qrc file compiles:
    1>------ Rebuild All started: Project: DrivenController, Configuration: Debug x64 ------
    1>Uic'ing DrivenManagerDialog.ui...
    1>Rcc'ing DrivenController.qrc...
    [...]
    and generates a qrc_DrivenController.cpp file, which gets compiled in turn:
    1>qrc_DrivenController.cpp
    1> Creating library C:\Users[...]DrivenController.lib

    ⦁ Loading the icon from an external file QIcon s_mutedIcon("C:\Users[...]Images\muted.png")
    works fine so there should be nothing wrong with the image file itself. Yet trying to load it from resource fails:
    QIcon mutedIcon(":/DrivenController/Images/muted.png");
    A pixmap constructed with the resources is Null.
    ⦁ I tried to enumerate all resources using this snippet:
    QDirIterator iter(":", QDirIterator::Subdirectories);
    while (iter.hasNext()) {
    qDebug() << iter.next();
    }
    ":/DrivenController/Images/muted.png" is missing from the list, as are all resources from DrivenControler.qrc.

    So it looks like the problem is that the content of DrivenControler.qrc does not make its way to available Qt resources. Does anyone have suggestions or a clue what I am missing?

    Thanks for suggestions


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Since you are talking about dll, I think you are in the case described here in the Qt Resources documentation.



  • @SGaist

    Thanks a lot!

    It looks like a call to Q_INIT_RESOURCE should have fixed the issue, but has not.

    I tried:
    ⦁ recreating the qrc file from scratch, and giving it a distinct name ('QtResource.qrc') in case there would be an unexpected name clash
    ⦁ calling Q_INIT_RESOURCE(QtResource) at misc points in time, from the DLL_PROCESS_ATTACH in DllMain, to in the ctor of a static library variable, to before use. No matter where I place it, the project qt resources are not among the resources listed enumerating all resources with the above code snippet, and unsurprisingly icon creation fails.


  • Lifetime Qt Champion

    Please post exactly what you try to do (do you use a static lib?) and some example code incl. an example qrc file.



  • @Christian-Ehrlicher
    Thank you for your offer to help!

    I am creating a dll not a static lib, and failing to access the Qt resources inside my dll code, not from the app code.
    Say I have two image files in file QtResouce,qrc. Here is what the resource editor shows:
    Resource
    The call to Q_INIT_RESOURCE with the base name of the .qrc file, not in any namespace:

    static void InitQrcResources()
    {
    	static bool init = false;
    	if (!init) {
    		init = true;
    		Q_INIT_RESOURCE(QtResource);
    	}
    }
    

    I experimented, but here I am assuming Q_INIT_RESOURCE has to be called once but no more. Then the code that attempts to access the resources

    InitQrcResources();
    	QListWidgetItem* item = new QListWidgetItem;
    [...]
    		QPixmap pixActiveFromQrc(":/DrivenController/Images/check.png");
    		// pixActiveFromQrc.isNull() is true
    		QPixmap pixActiveFromFile("C:\\Images\\check.png");
    		// pixActiveFromFile.isNull() is false
    		QIcon activeIcon(":/DrivenController/Images/check.png");
    		item->setIcon(activeIcon);
    		// no icon on the listWidgetItem
    

    Building...

    1>Rcc'ing QtResource.qrc...
    1>qrc_QtResource.cpp
    1>DrivenController.vcxproj -> C:\...\Plugins\DrivenController.dll
    

  • Lifetime Qt Champion

    Did you read the section about the namespace:
    "Note: As the resource initializers generated by rcc are declared in the global namespace, your calls to Q_INIT_RESOURCE() also need to be done outside of any namespace."
    Does it work when you link the resource directly to your app / main.cpp`?



  • @Christian-Ehrlicher
    Did you read the section about the namespace?
    I had read it, and noted it in my message.

    I didn't believe I was in any namespace, since I don't have any namespace declaration in my library, but just in case I tested with this snipet of code, and... function InitQrcResources() is not in any namespace.

    template <class A, class B>
    struct AreSame { enum { VALUE = -1 }; };
    template <class A>
    struct AreSame<A, A> { enum { VALUE = 1 }; };
    
    struct TestGlobalNamespace
    {
    	int test_namespace[AreSame<TestGlobalNamespace, ::TestGlobalNamespace>::VALUE];
    };
    
    

    I really don't know what more I could do to make sure I am not in any namespace.

    Finally, I don't have access to the app code, I am developing a plug-in as a dynamic link library. Is it possible that the app somehow locks the Qt resources? Is there a specific point in time where that INIT call has to be done? That Qt INIT call just pulls the transfer of the resource file content into the Qt file system?

    Does the presence of standard windows resource (.rc) interfere with Qt resources?

    I have really run out of ideas


  • Lifetime Qt Champion

    I would suggest you to start with a simple example of a library which provides qt resources and see if it works. If not then please post the example code here so we can take a look.



  • FYI, I've tested with a small dll project in QtCreator.
    Reading resources from a qrc file which is added to the same project doesn't need to call Q_INIT_RESOURCE at all.



  • For anyone interested: the app and my dll were using different qt library versions.


Log in to reply