PDA

View Full Version : Custom Widgets loading in Designer, but unable to find headers in Creator



Polnareff
18th May 2010, 21:18
Hi,

I've created a set of custom widgets with plugins. My project file looks like so:


CONFIG += designer \
plugin \
release
TEMPLATE = lib
TARGET = PCustomWidgetGroup
HEADERS += pframe.h \
punitspinbox.h \
punitslider.h \
pcustomwidgetgroupplugin.h \
punitwidget.h
SOURCES += pframe.cpp \
punitspinbox.cpp \
punitslider.cpp \
punitwidget.cpp
FORMS += pframe.ui \
punitspinbox.ui \
punitslider.ui
target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target


Despite the fact that I have the INSTALLS line, the *.a and *.dll files don't actually get copied to that folder. Up to now I've been manually copying them myself, although I would like to know why this occurs (but this is only a small problem atm...).

Now, when I load QT Designer, all my custom widgets show up and work fine. Unfortunately, this isn't the case in any project I create in QT Creator. It has problems finding the header files at compile time. Of course, this makes sense to me, since it doesn't seem like the headers are being copied to any folder.

I added the following line to my project file above, as per a tutorial online...


INCLUDEPATH += $$QT_SOURCE_TREE/tools/designer/interfaces

But alas, still no luck. I also added the following to my current project's .pro file:


LIBS += PCustomWidgetGroup

And nothing. I can't seem to find anything which adequately explains what folder my headers should be placed in, or how to do it automatically via the makefile. And, again, I'm unable to get the .a and .dll files copied without doing so manually.

Perhaps there's just something I'm doing entirely wrong and someone could snap me out of it :) All help is greatly appreciated! Thanks!

wysota
18th May 2010, 21:22
Despite the fact that I have the INSTALLS line, the *.a and *.dll files don't actually get copied to that folder. Up to now I've been manually copying them myself, although I would like to know why this occurs (but this is only a small problem atm...).
Are you running "make install" after the compilation (you might need superuser privileges)?


Now, when I load QT Designer, all my custom widgets show up and work fine. Unfortunately, this isn't the case in any project I create in QT Creator. It has problems finding the header files at compile time. Of course, this makes sense to me, since it doesn't seem like the headers are being copied to any folder.
And where did you copy the headers to?


And nothing. I can't seem to find anything which adequately explains what folder my headers should be placed in, or how to do it automatically via the makefile. And, again, I'm unable to get the .a and .dll files copied without doing so manually.
You can place the headers anywhere you want. Just make sure you add this directory to INCLUDEPATH variable in all projects that need to use those files.

Polnareff
19th May 2010, 13:53
Are you running "make install" after the compilation (you might need superuser privileges)?

Well I simply ran build from the QT Creator. I'm also doing this on my work computer, so it's very likely it has to do with user privileges. I'll look into it, thanks.


You can place the headers anywhere you want. Just make sure you add this directory to INCLUDEPATH variable in all projects that need to use those files.

Okay, I did this. The errors I am getting now:


debug/mainwindow.o:C:\Documents and Settings\amaior\Desktop\Projects\IntegratedCustomW idgets/ui_mainwindow.h:54: undefined reference to `_imp___ZN6PFrameC1EP7QWidget'
debug/mainwindow.o:C:\Documents and Settings\amaior\Desktop\Projects\IntegratedCustomW idgets/ui_mainwindow.h:61: undefined reference to `_imp___ZN12PUnitSpinBoxC1EP7QWidget'
debug/mainwindow.o:C:\Documents and Settings\amaior\Desktop\Projects\IntegratedCustomW idgets/ui_mainwindow.h:68: undefined reference to `_imp___ZN11PUnitSliderC1EP7QWidget'

From a bit of research, I found that it may have to do with adding libs to my project...unsure though, currently I just add the includepath for the headers.

wysota
19th May 2010, 15:47
Well I simply ran build from the QT Creator.
Creator runs "make", not "make install".


From a bit of research, I found that it may have to do with adding libs to my project...unsure though, currently I just add the includepath for the headers.
That's not enough. You need to link the project against the actual code of the widget, either by compiling the widget files directly with your project or by linking to a library containing the widget implementation (like the plugin library). The plugin itself is only meant for Designer.

Polnareff
19th May 2010, 16:03
That's not enough. You need to link the project against the actual code of the widget, either by compiling the widget files directly with your project or by linking to a library containing the widget implementation (like the plugin library). The plugin itself is only meant for Designer.

By adding the header files and including it via the INCLUDEPATH, isn't that what I'm doing?

wysota
19th May 2010, 16:19
No. Header files only contain declarations of functions and classes. When you use Qt it is not enough to include Qt headers in your project, you need to link to actual Qt libraries (dlls), right? That's the same case here.

Polnareff
19th May 2010, 16:34
Ah, that makes sense. Okay well I've re-compiled my widget with mvsc (mostly because I want to be able to add the widgets from QT Creator's designer), and copied the lib into a folder called lib in my project root. So I have

/include/punitspinbox.h (there are others, but this is the only one I'm using at the moment)
/lib/PCustomWidgetGroup.lib

I've added the following lines to my project file:
INCLUDEPATH += ./include
LIBS += -lib -PCustomWidgetGroup

The first problem I have is with the LIBS line...which I followed from tutorials. Either way, upon replacing it with an actual direct path to the lib file, it finds the lib file, but I get the following error:

C:/Documents and Settings/amaior/Desktop/Projects/IntegratedCustomWidgets/ui_mainwindow.h:49: undefined reference to `_imp___ZN12PUnitSpinBoxC1EP7QWidget'

wysota
19th May 2010, 17:03
Your LIBS line is surely incorrect. It should say LIBS += -lnameofthelibrary, i.e. -lmyplugin (if your lib is called myplugin.dll).

Polnareff
19th May 2010, 17:19
Your LIBS line is surely incorrect. It should say LIBS += -lnameofthelibrary, i.e. -lmyplugin (if your lib is called myplugin.dll).

Thanks. I've fixed that, but the other error persists =/

wysota
19th May 2010, 17:48
Did you build the plugin with the same compiler you are using for compiling your projects? Also make sure you actually implemented the UnitSpinBox constructor taking a QWidget parameter. Remember about exporting the class from the DLL! In doubt, consult the documentation for Windows specifics.

Polnareff
19th May 2010, 19:57
I've decided to stop building with the mvsc compiler, and just stick to the one that QT Creator uses. And yes, the UnitSpinBox constructor takes a QWidget parameter.

Now I have two questions...

1. I made a macro to export my classes to DLL, and want to put it in the class definition. Except since my classes are also exported to designer, I need to have both macros in the class definition. Unfortunately, the following doesn't seem to work:

class SHAREDLIB_EXPORT QDESIGNER_WIDGET_EXPORT PUnitSpinBox : public PUnitWidget {
I also tried separating the macros by comma, with no success. What's the correct syntax for this?

2. Currently building doesn't ever produce a *.lib file. Is that normal? What am I supposed to link against without it? (please excuse my lack of knowledge on this stuff, I'm still learning)

wysota
19th May 2010, 20:11
You only need one macro, they both probably have the same contents.


2. Currently building doesn't ever produce a *.lib file. Is that normal?
If you don't have export macros then yes. That's why you need them :)

Polnareff
19th May 2010, 20:17
Shortly before your reply I realized the macros were doing the same thing :P

But that's just it, I've had the QDESIGNER_WIDGET_EXPORT macro in there the whole time, and I still don't have any lib file. Incase it's important, my .pro file is:


CONFIG += designer \
plugin \
release
TEMPLATE = lib
DEFINES += SHAREDLIB_LIBRARY

HEADERS += pcustomwidgetgroupplugin.h \
include(CustomWidgets.pri)

target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target

Am I missing something to create the lib file?

wysota
19th May 2010, 21:10
What's in CustomWidgets.pri?

Polnareff
20th May 2010, 11:49
HEADERS += pframe.h \
punitspinbox.h \
punitslider.h \
punitwidget.h \
sharedlib_global.h
SOURCES += pframe.cpp \
punitspinbox.cpp \
punitslider.cpp \
punitwidget.cpp
FORMS += pframe.ui \
punitspinbox.ui \
punitslider.ui

I only just introduced that. Those were originally in the pro file. It's just to clean it up a bit.

wysota
20th May 2010, 16:38
Do all your classes contain export macros?

Polnareff
20th May 2010, 17:55
These are my classes (--> denotes child class, and * denotes containing export macro)


PFrame*
PUnitWidget
--> PUnitSlider*
--> PUnitSpinBox*
//Plugins...
WidgetPlugin
PFramePlugin
PUnitSliderPlugin
PUnitSpinBoxPlugin
PCustomWidgetGroupPlugin (Q_EXPORT_PLUGIN2 is called on this class)


Do I need to be exporting all of them?

wysota
20th May 2010, 20:27
You should export all widget classes but if at least one class contains export macro, the .lib (or .a in case of MinGW) file should be created.

Polnareff
21st May 2010, 15:08
Well, believe it or not, I've gotten it to work! Thank you so much, by the way, for tolerating with me :) I understand this a lot better now, so it certainly helped.