PDA

View Full Version : Trouble loading UI (with images) from plugin (.so)



dcrespo
23rd February 2011, 21:10
Hi,

I have a plugin that loads and shows a custom widget that displays an image (as a background for a QLabel) loaded from a resource file (resources.qrc). The problem I'm facing is that once the plugin is loaded, it shows the widget properly, but not the image. I tried putting "Q_INIT_RESOURCE( resources )" everywhere, but nothing happens. I have created many custom widgets that use qrc files to display images, but only directly within an app, which have worked just fine. This time is from a plugin, so there must be something I'm missing here. Any help?



// TheInterface.h
class TheInterface
{
...
}
Q_DECLARE_INTERFACE(TheInterface,"com.system.subsystem.TheInterface/1.0");



// MyWidget.h
class MyWidget : public QWidget, public Ui::MyWidget
{
Q_OBJECT
...
}



// MyPlugin.h
#include "TheInterface.h"
class MyPlugin : public QOBject,
public TheInterface
{
Q_OBJECT
Q_INTERFACES(TheInterface)

...
};

// MyPlugin.cpp
#include "MyPlugin.h"
#include "MyWidget.h"
MyPlugin::MyPlugin()
{
MyPlugin* w = new MyPlugin();
w->show();
}

Q_EXPORT_PLUGIN2(myplugin, MyPlugin)

ChrisW67
23rd February 2011, 23:19
You don't show us any code that attempts to use a resource or where the "everywhere" you tried putting "Q_INIT_RESOURCE( resources )" was. It helps if you cut and paste your actual code rather than re-keying it and introducing errors, e.g. "QOBject" or the MyPlugin constructor trying to allocate another copy of MyPlugin on the heap (kinda recursive isn't it?).

I'm fairly sure the "Q_INIT_RESOURCE( resources )" should be in the MyPlugin constructor so that it executes when the plugin is loaded and before any factory method (assuming you have one) returns a MyWidget to the program.

dcrespo
24th February 2011, 00:03
Thanks for your response.

I'm sorry for the errors. You are right, but I'm not allowed to paste the whole code.

In MyPlugin constructor, what I meant was:



MyPlugin::MyPlugin()
{
MyWidget* w = new MyWidget();
w->show();
}


The resource is used from within the UI. My .pro file looks like this:



TEMPLATE = lib
CONFIG += plugin debug resources
INCLUDEPATH += /path/to #TheInterface.h

HEADERS = MyPlugin.h \
MyWidget.h

SOURCES = MyPlugin.cpp \
MyWidget.cpp

DEPENDPATH += . resources

RESOURCES += resources/resources.qrc

FORMS = mywidget.ui

TARGET = myplugin


Also, within MyWidget.h, I'm properly doing

#include "ui_mywidget.h"

I tried putting "Q_INIT_RESOURCE( resources )" in MyPlugin constructor, but no image is shown. I did the equivalent to the following:


MyPlugin::MyPlugin()
{
Q_INIT_RESOURCE( resources );
}


I did try to change "resources" for something buggy like "resourcesss" and at plugin loading time the error shown was:
... /path/to/my/libmyplugin.so: undefined symbol: _Z26qInitResources_resourcesssv

Any other idea?

Thanks

wysota
24th February 2011, 00:10
The error means you don't have a resource file called "resources" linked into your library.

dcrespo
24th February 2011, 17:24
Thanks for your response, but, please, read again. I made that error happen on purpose by putting a buggy value. Instead of specifying "resources" I put "resourcesss", just to prove that "resources" is ok, and "resourcesss" is not. So, back to the main question:

Why isn't an image (loaded from a resource file, resources.qrc) showing up in a widget that is loaded from a plugin?

Thanks again.

wysota
24th February 2011, 20:33
What's the type of the image?

dcrespo
25th February 2011, 14:42
Problem solved.
Thanks a lot for your responses.

The problem was that the main application has already a qrc file with the same name (resources.qrc). The plugin, being loaded by the main app, has a different resources.qrc file, but because the main app had one already, it was not loading it. I changed the name of the resource file in the plugin, worked perfectly. Of course, I had to change the "Q_INIT_RESOURCE( resources );" to "Q_INIT_RESOURCE( new_resource_file_basename );". Also, it was enough to call this in the constructor of the MyWidget class. In other words, it does NOT need to be in the constructor of the plugin (MyPlugin::MyPlugin()). It makes sense, since the MyWidget is the one using the resource file, not the plugin.

Thanks again for your support.

-Daniel