Custom Widget doesn t show.
I have created a custom widget and a plugin for that widget in Designer. I have tested the custom widget localy and it works fine. The widget appears in the widget box in designer/form editor and I can drag i it to my window hand handle the signals & and slots. But when I hit preview or compile the widget doesn´t show. I do not get any error messages and when i look into the generated ui_XXXXX.h and it looks fine. What am I missing? Could Upload All code......
customDial.proj
Code:
CONFIG += designer \
plugin \
debug_and_release
TARGET = $$qtLibraryTarget(speeddialplugin)
TEMPLATE = lib
HEADERS = speeddialplugin.h \
qtsvgdialgauge.h \
qtsvgpixmapcache.h
SOURCES = speeddialplugin.cpp \
qtsvgdialgauge.cpp \
qtsvgpixmapcache.cpp
RESOURCES = icons.qrc \
skins.qrc
LIBS += -L.
target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
# include(speeddial.pri)
QT += svg
speedDialPlugin.h
Code:
#ifndef SPEEDDIALPLUGIN_H
#define SPEEDDIALPLUGIN_H
#include <QtDesigner/QDesignerCustomWidgetInterface>
#include <QObject>
#include <Qt>
{
Q_OBJECT
public:
speedDialPlugin
(QObject *parent
= 0);
bool isContainer() const;
bool isInitialized() const;
private:
bool m_initialized;
};
#endif
speedDialPlugin.cpp
Code:
#include "qtsvgdialgauge.h"
#include "speeddialplugin.h"
#include <QtCore/QtPlugin>
speedDialPlugin
::speedDialPlugin(QObject *parent
){
m_initialized = false;
}
{
if (m_initialized)
return;
// Add extension registrations, etc. here
m_initialized = true;
}
bool speedDialPlugin::isInitialized() const
{
return m_initialized;
}
{
//return new speedDial(parent);
QtSvgDialGauge * gauge = new QtSvgDialGauge(parent);
gauge->setSkin("Tachometer");
gauge->setMinimum(0);
gauge->setMaximum(120);
gauge->setValue(0);
return gauge;
}
QString speedDialPlugin
::name() const {
}
QString speedDialPlugin
::group() const {
}
QIcon speedDialPlugin
::icon() const {
}
QString speedDialPlugin
::toolTip() const {
}
QString speedDialPlugin
::whatsThis() const {
}
bool speedDialPlugin::isContainer() const
{
return false;
}
QString speedDialPlugin
::domXml() const {
return QLatin1String("<widget class=\"speedDial\" name=\"speedDial\">\n</widget>\n");
}
QString speedDialPlugin
::includeFile() const {
}
Q_EXPORT_PLUGIN2(speeddialplugin, speedDialPlugin)
qtSvgDialGauge.h
Code:
/*
*/
#ifndef QT_SVG_DIAL_GAUGE
#define QT_SVG_DIAL_GAUGE
#include <QtGui/QWidget>
#include <Qt>
#include <QtCore/QPair>
#include <QtDesigner/QDesignerExportWidget>
class QtSvgPixmapCache;
class QDESIGNER_WIDGET_EXPORT QtSvgDialGauge
: public QWidget{
Q_OBJECT
Q_PROPERTY(QString skin READ skin WRITE setSkin
) Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
Q_PROPERTY(qreal startAngle READ startAngle WRITE setStartAngle)
Q_PROPERTY(qreal endAngle READ endAngle WRITE setEndAngle)
public:
explicit QtSvgDialGauge
(QWidget * parent
= 0);
~QtSvgDialGauge();
void setSkin(const QString& skin);
void setMinimum(int minimum);
void setMaximum(int maximum);
void setNeedleOrigin(qreal x, qreal y);
void setStartAngle(qreal angle);
void setEndAngle(qreal angle);
int value() const;
int minimum() const;
int maximum() const;
qreal needleOriginX() const;
qreal needleOriginY() const;
qreal startAngle() const;
qreal endAngle() const;
virtual QSize minimumSizeHint
() const;
virtual QSize sizeHint
() const;
void setShowOverlay(bool);
public slots:
void setValue(int value);
private:
void init();
QRectF availableRect
(QtSvgPixmapCache
* renderObject
) const;
QtSvgPixmapCache* m_backgroundRenderer;
QtSvgPixmapCache* m_needleShadowRenderer;
QtSvgPixmapCache* m_overlayRenderer;
/** minimum possible value **/
int m_minimum;
/** maximum possible value **/
int m_maximum;
/** actual value **/
int m_value;
/** smallest start angle **/
qreal m_startAngle;
/** highest end angle **/
qreal m_endAngle;
/** position x of needle **/
qreal m_originX;
/** position y of needle **/
qreal m_originY;
bool m_showOverlay;
/** name of actual skin **/
protected:
};
#endif // QT_SVG_DIAL_GAUGE
qtSvgDialGauge.cpp
Code:
/*
*/
#include <QtGui/QPainter>
#include <QtSvg/QSvgRenderer>
#include "qtsvgdialgauge.h"
#include "qtsvgpixmapcache.h"
/*!
\class QtSvgDialGauge qtsvgdialgauge.h
\code
// Create a QtSvgDialGauge
QWidget * widget = new QWidget(this)
QtSvgDialGauge * gauge = new QtSvgDialGauge(widget);
gauge->setSkin("Beryl");
widget->addWidget(gauge);
widget->show();
\endcode
/*!
Constructor of the widget with \p parent as
Parent.
*/
QtSvgDialGauge
::QtSvgDialGauge(QWidget * parent
) m_minimum(0),
m_maximum(100),
m_value(0),
m_startAngle(0),
m_endAngle(100),
m_originX(0.5),
m_originY(0.5),
m_showOverlay(true)
{
init();
}
/*!
Destructor
*/
QtSvgDialGauge::~QtSvgDialGauge()
{
}
/*.....
......
.....
.....
.....
.....*/
}
qtSvgPixmapCache.h
Code:
/*
*/
#ifndef QT_SVG_PIXMAP_CACHE
#define QT_SVG_PIXMAP_CACHE
#include <QtCore/QSizeF>
#include <Qt>
#include <QObject>
#include <QtDesigner/QDesignerExportWidget>
class QtSvgPixmapCachePrivate;
class QDESIGNER_WIDGET_EXPORT QtSvgPixmapCache
: public QObject{
Q_OBJECT
public:
QtSvgPixmapCache
(QObject* parent
= NULL);
#endif // QT_SVG_PIXMAP_CACHE
qtSvgPixmapCache.cpp
Re: Custom Widget doesn t show.
How did you implement sizeHint()?
Re: Custom Widget doesn t show.
/*!
\internal
\overload
Set default size hint. Can be changed at runtime.
*/
QSize QtSvgDialGauge::sizeHint() const
{
return QSize(400, 400);
}
Re: Custom Widget doesn t show.
Re: Custom Widget doesn t show.
Quote:
Originally Posted by
Frej
I have been testing the widget localy i.e. not as a plugin and then it works fine. So it should be any problem with widget code as I see. It has to be the plugin or how i setup the .pro file or something.
Hmm... earlier you said it worked fine when previewing the widget in Designer but not after compiling the code. Or at least so I understood... Can you say again when it works and when it doesn't work? And also how the widget works in general (mainly where does it get data from for the renderer).
Re: Custom Widget doesn t show.
The widgetplugin appears in the widgetbox in designer/form editor and i can drag it to my canvas and it is displayed as it should. I can connect signals and slot to it. Butwhen I hit preview in designer or when I compile the application the widget doesn´t show anymore. If I don´t use it as a plugin but just includes the widget code I can manually (in code) create an instance of my widget and it works fine. So it seems to be the plugin that is the problem. My widget uses vector graphics (svg) images that are painted on top of each other with specified relations. So svg files are loaded and ordered in a structured way and then a special renderer takes care of rendering for different platforms and so....
pixmapcache.h
Code:
#include "qtsvgpixmapcache.h"
#include <QtGui/QPainter>
#include <QtSvg/QSvgRenderer>
#if defined(Q_WS_HILDON) && (QT_VERSION < 0x040500)
# define QT_MAEMO_XRENDER_ALPHA_BUG
# warning Using workaround for 'XRender and QPixmap with alpha' drawing bug
#endif
class QtSvgPixmapCachePrivate
{
public:
void updatePixmapCache(const QSizeF& size);
public:
#ifdef QT_MAEMO_XRENDER_ALPHA_BUG
#else
#endif
};
, d(new QtSvgPixmapCachePrivate())
{
}
QtSvgPixmapCache::QtSvgPixmapCache(const QString& url)
: d(new QtSvgPixmapCachePrivate())
{
load(url);
}
QtSvgPixmapCache::~QtSvgPixmapCache()
{
delete d;
}
bool QtSvgPixmapCache::load(const QString& url)
{
d->svgRenderer.load(url);
#ifdef QT_MAEMO_XRENDER_ALPHA_BUG
#else
#endif
return d->pixmapCache.isNull();
}
bool QtSvgPixmapCache::isValid() const
{
return d->svgRenderer.isValid();
}
void QtSvgPixmapCache
::render(QPainter* painter,
const QRectF
& bounds
) {
if (!d->svgRenderer.isValid()) {
return;
}
if (d->pixmapCache.isNull() || bounds.size().toSize() != d->pixmapCache.size()) {
d->updatePixmapCache(bounds.size());
}
#ifdef QT_MAEMO_XRENDER_ALPHA_BUG
painter->drawImage(bounds.topLeft(), d->pixmapCache);
#else
painter->drawPixmap(bounds.topLeft(), d->pixmapCache);
#endif
}
QSize QtSvgPixmapCache
::defaultSize() const {
return d->svgRenderer.defaultSize();
}
void QtSvgPixmapCachePrivate::updatePixmapCache(const QSizeF& size)
{
#ifdef QT_MAEMO_XRENDER_ALPHA_BUG
pixmapCache
= QImage(size.
toSize(),
QImage::Format_ARGB32_Premultiplied);
#else
pixmapCache
= QPixmap(size.
toSize());
#endif
pixmapCache.fill(Qt::transparent);
svgRenderer.render(&painter);
painter.end();
}
Re: Custom Widget doesn t show.
What happens if you compile a standalone program using that widget of yours but not by including the widget files directly into the project but instead by linking with the plugin library? Because the plugin has nothing to do with your application - it is only used by Designer. If you build an application that uses it, you have to link with the code of the widget regardless of the existance of the plugin.
Re: Custom Widget doesn t show.
Yeah I think the linking to my libspeeddial.so is what is going wrong. If I just include LIBS += "/home/frej/qtsdk-2010.01/bin/designer/libspeeddialplugin.so" in my pro file i should be able to use my widget something like this:
#include "speeddialplugin.h"
speedDialPlugin *p = new speedDialPlugin();
QWidget *gauge = p->createWidget(parent);
setCentralWidget(gauge);
But this does´t work, I aslo have to add include paths to my speeddialplugin for this to work. I assumed i vould just link to the lib file and it would contain alll logic is that wrong, if not it seem like it is the linking that is not working.
Re: Custom Widget doesn t show.
Please explain what "doesn't work" means in this case. You always need the header file, the library itself is not enough (you need Qt header files to use Qt too, right?).
Re: Custom Widget doesn t show.
If i create a new project and add LIBS += "/home/frej/qtsdk-2010.01/bin/designer/libspeeddialplugin.so" to link to my speeddialplugin. It i then try to write something like this:
#include "speeddialplugin.h"
speedDialPlugin *p = new speedDialPlugin();
QWidget *gauge = p->createWidget(parent);
setCentralWidget(gauge);
But this doesn´t work, error: speeddialplugin.h: No such file or directory.
So I have to add includepaths to my speeddialplugin.h, INCLUDEPATH += "/home/frej/Documents/Qt Dev/customDial". Then it works fine to create an instance of my widget like
speedDialPlugin *p = new speedDialPlugin();
QWidget *gauge = p->createWidget(parent);
setCentralWidget(gauge);
But if instead by adding the widget by code, but drag n drop from the widget box instead, then I get the problem with the widget not showing when I compile or hit preview.
(Thanx for beeing patient)
Re: Custom Widget doesn t show.
But why include the plugin header? You only need the widget header. If you can't see the widget in the compiled code then inspect the code created by uic (ui_speeddial.h) to see if it creates your widget properly. If it does then the problem is in your widget code. Make sure the paint event is called and that the size of the widget is valid (during that paint event). Once you verify that we can continue looking for problems.
Re: Custom Widget doesn t show.
Found the problem now. Since i didn´t set a skin in my constructor (to leave it to the user) no background image where set, so the widget was there but it didn´t contain any graphic. Sorry for bothering you with this silly problem. On the upside i think I learnt alot on how plugins work.