PDA

View Full Version : QT4 custom designer plugin properties ignored



Intangir
15th June 2006, 20:57
i have a problem with some custom designer plugins

they derive from QDesignerCustomWidgetInterface
i followed all the instructions, they override functions:
QIcon icon() const;
QString codeTemplate() const;
QString domXml() const;
QString group() const;
QString includeFile() const;
QString name() const;
QString toolTip() const;
QString whatsThis() const;
QWidget * createWidget( QWidget * parent );
void initialize( QDesignerFormEditorInterface * core );
bool isInitialized() const;
bool isContainer() const;


I am including them all in one lib file though, and they are compiling from the same files. so i cant use Q_EXPORT_PLUGIN2() macro for each one

but there is this QDesignerCustomWidgetCollectionInterface class which im using which lets you do exactly that, include more than one customwidget in one lib, it says to use Q_EXPORT_PLUGIN2() only for the collection

i followed the instructions exactly..
i build it, it loads up in designer..
THE PROBLEM IS:

in qt3 it ignores all of the isContainer, includeFile name, tooltip, whatsThis, when writing out the .ui file
fortunately whatever the defaults it picks. work ok for most of my plugins when it uic's them and generates .h files and whatnot, they are ok, the includes somehow work anyway. and it doesnt set any container flag like it shouldnt (cause its not a container)


so qt3 designer ignores those methods, but whatever defaults it comes up with work anyway when it writes the .ui file and uic runs on them. (except for on one of my plugins..


on qt4 it also ignores them but comes up with lousier defaults, and writes them in the .ui file!!

it tries to include header files that dont exist, that i didnt put ANYWHERE!! (the plugin name in all lowercase with a .h, and with no path)

it also flags it as a container when its not

its very unusual and frustrating

so both qt3 and qt4 are doing it wrong, the qt3 by chance works for most of my plugins anyway, and the qt4 doesnt

jacek
15th June 2006, 21:17
Can we see some code? How did you define the classes that implement QDesignerCustomWidgetInterface? Do they inherit QObject?

Do I understand you correctly, that you are trying to use a Qt4 custom widget plugin with Qt Designer from Qt3?

Intangir
15th June 2006, 22:23
no, im trying to make a custom designer plugin, for either qt3 or qt4

neither work correctly

the .ui file you save off with your custom widgets has this block like this:
<customwidgets>
<customwidget>
<class>AnalogClock</class>
<extends></extends>
<header>analogclock.h</header>
<container>0</container>
<pixmap></pixmap>
</customwidget>
</customwidgets>

notice the header file above says analogclock.h..
but the source its supposed to use to get that says:

QString AnalogClockPlugin::includeFile() const
{
return "mycustom.h";
}


notice the header file is DIFFERENT...

apparently it has nothing to do with the collectionInterface.. it just plain doenst work..

i cant use qtdesigner to layout my custom widgets unless i have the header files with that default naming, lowercase of the name, with .h on the end.. this isnt very useful..

that block is from a qt4 generated .ui file
i think qt3 just leaves that block out completely, and it comes up with defaults some other way


i dont know how it comes up with these defaults though, in one of or our projects it flags our custom plugins as containers when they arent..



this is very frustrating, the docs for plugins for designer is vague and its examples, straight off the 4.1 docs dont work right


to see what i mean go here:
http://doc.trolltech.com/4.1/designer-customwidgetplugin.html

download those source files at the top
im using this for a .pro file:

CONFIG += designer plugin debug_and_release
TEMPLATE = lib

HEADERS += src/analogclock.h \
src/customwidgetplugin.h
SOURCES += src/analogclock.cpp \
src/customwidgetplugin.cpp
TARGET= bin/customplug


i had to fix an include path on one of the sources but i forget which



anyway change the header to something besides the default
set container to something differnet

build it, copy it into plugins/designer directory and run designer-qt4

make a ui, put your custom control on it, save a .ui file

then check that .ui file, it will still have only the defaults saved in it, isntead of your actual custom headers and flags from your source :(

this makes it faily useless for massive projects where your includes are in subdirectories

basically you end up not being able to layout your custom widgets in designer at all, i have to dynamically put them up on forms at runtime..

this sucks ;(

i thought it was something i was doing wrong but i check even the examples right off the website and they are also doing it wrong


maybe im just misunderstanding the point of those methods but if they arent for saving includes and junk into the .ui file, what else could they possible be for?

Intangir
15th June 2006, 22:26
and before you wonder, yes i am copying the newly built plugin file to the plugins/designer directory after i make changes to it

Intangir
15th June 2006, 22:33
and to clarify MY problem with this problem is that i need to be able to define my own header files to be included when using the plugins from a .ui file

when it does the uic step it generates files that include headers which dont exist, cause the plugin's:
QString AnalogClockPlugin::includeFile() const
{
return "mycustom.h";
}

is ignored :(

jacek
15th June 2006, 23:12
I was able to reproduce your problem and it seems that Designer gets confused when you have two plugins for widgets with the same class name.

Make sure:
that the name of a class in XML snippet returned by domXml() and the string returned by name() are the same as the widget's class name,
that there are no other plugins which name() method returns the same string (you might already have one plugin for AnalogClock widget installed),
and finally that you compile your plugin in release mode.

Rename AnalogClock to something like AnalogClockX, update your plugin's code:

...

QString AnalogClockPlugin::name() const
{
return "AnalogClockX";
}

...

QString AnalogClockPlugin::domXml() const
{
return "<widget class=\"AnalogClockX\" name=\"analogClock\">\n"
...
"</widget>\n";
}

...

QString AnalogClockPlugin::includeFile() const
{
return "mycustom.h";
}
and run:
make -f Makefile.ReleaseAfter this you should get a working plugin:
<customwidget>
<class>AnalogClockX</class>
<extends>QWidget</extends>
<header>mycustom.h</header>
<container>0</container>
<pixmap></pixmap>
</customwidget>

Intangir
15th June 2006, 23:29
awesome
ok now at least i have a working example ;)
i gotta figure out if this is what could be causing my issue with my custom widgets in my collection

they are having issues too but they have unique names


im going to try and alter this example code to use a collection and see if all of the widgets in the collection work. or not

now i have a working plugin to experiment off of though!

thanks jacek!

mister_wang
23rd May 2015, 12:56
I was able to reproduce your problem and it seems that Designer gets confused when you have two plugins for widgets with the same class name.

Make sure:
that the name of a class in XML snippet returned by domXml() and the string returned by name() are the same as the widget's class name,
that there are no other plugins which name() method returns the same string (you might already have one plugin for AnalogClock widget installed),
and finally that you compile your plugin in release mode.

Rename AnalogClock to something like AnalogClockX, update your plugin's code:

...

QString AnalogClockPlugin::name() const return "AnalogClockX";
}

...

QString AnalogClockPlugin::domXml() const
{
return "<widget class=\"AnalogClockX\" name=\"analogClock\">\n"
...
"</widget>\n";
}

...

QString AnalogClockPlugin::includeFile() const
{
return "mycustom.h";
}
and run:
make -f Makefile.ReleaseAfter this you should get a working plugin:
<customwidget>
<class>AnalogClockX</class>
<extends>QWidget</extends>
<header>mycustom.h</header>
<container>0</container>
<pixmap></pixmap>
</customwidget>

This doesnt work. 100%





QWidget *TestPlugin::createWidget(QWidget *parent)
{
return new CustomControls::CheckBox(parent);
}

QString TestPlugin::name() const
{
return QLatin1String("CheckBox");
}

QString TestPlugin::domXml() const
{
return QLatin1String("<widget class=\"CustomControls::CheckBox\" name=\"cb\">\n"
"</widget>\n");
}

QString TestPlugin::includeFile() const
{
return QLatin1String("checkbox.h");
}


it gives me

<customwidgets>
<customwidget>
<class>CustomControls::CheckBox</class>
<extends>QWidget</extends>
<header>customcontrols::checkbox.h</header>
</customwidget>
</customwidgets>

and it doesn't matter what you return in function includeFile(). Header file been generated automatically from widget class