How to load multiple custom plugins for form editor in Qt Creator
-
I tried making plugins for Qt Creator Designer but I'm not able to load more than one plugin at a time it shows error message "multiple definition of `qt_plugin_query_metadata' "
moc_tankplugin.o: In function
qt_plugin_query_metadata': moc_tankplugin.cpp:(.text+0x30): multiple definition of
qt_plugin_query_metadata'
moc_LEDPlugin.o:moc_LEDPlugin.cpp:(.text+0x30): first defined here
moc_tankplugin.o: In functionqt_plugin_instance': moc_tankplugin.cpp:(.text+0x40): multiple definition of
qt_plugin_instance'
moc_LEDPlugin.o:moc_LEDPlugin.cpp:(.text+0x40): first defined here
collect2: error: ld returned 1 exit statustankplugin.h
#ifndef TANKPLUGIN_H
#define TANKPLUGIN_H#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class TankPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "com")
#endif // QT_VERSION >= 0x050000public:
TankPlugin(QObject *parent = 0);bool isContainer() const; //bool isInitialized() const; QIcon icon() 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);
private:
// bool m_initialized;
bool initialized;
};#endif
Similarly
LEDPlugin.h (Used this file as reference which is developed my Mark Wilson at ICS)
#ifndef LED_PLUGIN_H
#define LED_PLUGIN_H#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class LEDPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
Q_PLUGIN_METADATA(IID "com.ics.Qt.CustomWidgets")
#endifpublic:
LEDPlugin(QObject* parent=0);QString name() const; QString group() const; QString toolTip() const; QString whatsThis() const; QString includeFile() const; QIcon icon() const; bool isContainer() const; QWidget *createWidget(QWidget *parent);
private:
bool initialized;
};#endif
-
Hi and welcome to devnet,
How is your project structured ?
-
It's a project with only two widgets loaded in the QMainWindow using form editor and then tried building the project. Custom Widgets are used in the project. So I have included the .so files of both tank and LED in the plugins folder of Qt and its creator. Here are all the files of the project (name - untitled2) -
untitled2.pro
mainwindow.h (Automatically Generated)
LED.h
LEDPlugin.h
tank.h (Almost made using same logic as LED)
tankplugin.h
mainwindow.cpp (Automatically Generated)
LED.cpp
LEDPlugin.cpp
tank.cpp (Almost made using same logic as LED)
tankplugin.cpp
main.cpp (Automatically generated)
mainwindow.ui (Have a tank and LED)untitled2.pro
QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled2
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGSSOURCES +=
main.cpp
mainwindow.cpp
LED.cpp
LEDPlugin.cppHEADERS +=
mainwindow.h
LED.h
LEDPlugin.hFORMS +=
mainwindow.uimainwindow.h (Automatically generated)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QtWidgets/QMainWindow>
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();protected:
void changeEvent(QEvent *e);private:
Ui::MainWindow *ui;
};#endif // MAINWINDOW_H
LED.h
#ifndef LED_H
#define LED_H#include <QtDesigner/QtDesigner>
#include <QWidget>class QTimer;
class QDESIGNER_WIDGET_EXPORT LED : public QWidget
{
Q_OBJECTQ_PROPERTY(double diameter READ diameter WRITE setDiameter) // mm Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) Q_PROPERTY(bool state READ state WRITE setState) Q_PROPERTY(bool flashing READ isFlashing WRITE setFlashing) Q_PROPERTY(int flashRate READ flashRate WRITE setFlashRate)
public:
explicit LED(QWidget* parent=0);
~LED();double diameter() const; void setDiameter(double diameter); QColor color() const; void setColor(const QColor& color); Qt::Alignment alignment() const; void setAlignment(Qt::Alignment alignment); bool state() const; bool isFlashing() const; int flashRate() const;
public slots:
void setState(bool state);
void toggleState();
void setFlashing(bool flashing);
void setFlashRate(int rate);
void startFlashing();
void stopFlashing();public:
int heightForWidth(int width) const;
QSize sizeHint() const;
QSize minimumSizeHint() const;protected:
void paintEvent(QPaintEvent* event);private:
double diameter_;
QColor color_;
Qt::Alignment alignment_;
bool initialState_;
bool state_;
int flashRate_;
bool flashing_;// // Pixels per mm for x and y... // int pixX_, pixY_; // // Scaled values for x and y diameter. // int diamX_, diamY_; QRadialGradient gradient_; QTimer* timer_;
};
#endif
tank.h
#ifndef TANK_H
#define TANK_H#include <QtDesigner/QtDesigner>
#include <QWidget>class QDESIGNER_WIDGET_EXPORT Tank : public QWidget
{
Q_OBJECTQ_PROPERTY(int width READ width WRITE setWidth) // mm Q_PROPERTY(int halfheight READ halfheight WRITE sethalfHeight) // mm Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) Q_PROPERTY(int upperRange READ upperRange WRITE setupperRange) Q_PROPERTY(int lowerRange READ lowerRange WRITE setlowerRange)
public:
//explicit Tank(int,int,int,int,int,int,QWidget *parent = 0);
explicit Tank(QWidget *parent = 0);
~Tank(){};int width() const; void setWidth(int width); int halfheight() const; void sethalfHeight(int halfheight); QColor color() const; void setColor(const QColor color); Qt::Alignment alignment() const; void setAlignment(Qt::Alignment alignment); int upperRange() const; int lowerRange() const;
protected:
void paintEvent(QPaintEvent* event);//for configuration with layouts
public:
int heightForWidth(int width) const;
QSize sizeHint() const;
QSize minimumSizeHint() const;//used variables
private:
int myX,myY,Width,halfHeight,myUpperRange,mylowerRange;
int myLevel;
QColor myColor;
Qt::Alignment myAlignment;private slots:
void setLevel(int);
void setlowerRange(int);
void setupperRange(int);
};#endif
main.cpp (Automatically Generated)
#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();return a.exec();
}
mainwindow.cpp (Automatically Generated)
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}LEDPlugin.cpp
#include "LED.h"
#include "LEDPlugin.h"
#include <QtPlugin>LEDPlugin::LEDPlugin(QObject* parent) :QObject(parent),initialized(false)
{
}QString LEDPlugin::name() const
{
return "LED";
}QString LEDPlugin::group() const
{
return tr("ICS Custom Widgets");
}QString LEDPlugin::toolTip() const
{
return tr("An LED");
}QString LEDPlugin::whatsThis() const
{
return tr("An LED");
}QString LEDPlugin::includeFile() const
{
return "LED.h";
}QIcon LEDPlugin::icon() const
{
return QIcon();
}bool LEDPlugin::isContainer() const
{
return false;
}QWidget * LEDPlugin::createWidget(QWidget *parent)
{
return new LED(parent);
}#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
Q_EXPORT_PLUGIN(ledplugin, LEDPlugin)
#endiftankplugin.cpp
ifndef TANKPLUGIN_H
#define TANKPLUGIN_H#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class TankPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "com.ics.Qt.CustomWidgets")
#endif // QT_VERSION >= 0x050000public:
TankPlugin(QObject *parent = 0);bool isContainer() const; //bool isInitialized() const; QIcon icon() 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);
private:
// bool m_initialized;
bool initialized;
};#endif
LED.cpp (Used to build and update the LED)
#include <math.h>
#include <QPainter>
#include <QGradient>
#include <QPaintDevice>
#include <QTimer>
#include "LED.h"LED::LED(QWidget* parent) :
QWidget(parent),
diameter_(5),
color_(QColor("red")),
alignment_(Qt::AlignCenter),
initialState_(true),
state_(true),
flashRate_(200),
flashing_(false)
{
timer_ = new QTimer(this);
connect(timer_, SIGNAL(timeout()), this, SLOT(toggleState()));
setDiameter(diameter_);
}LED::~LED()
{
}double LED::diameter() const
{
return diameter_;
}void LED::setDiameter(double diameter)
{
diameter_ = diameter;pixX_ = round(double(height())/heightMM()); pixY_ = round(double(width())/widthMM()); diamX_ = diameter_*pixX_; diamY_ = diameter_*pixY_; update();
}
QColor LED::color() const
{
return color_;
}void LED::setColor(const QColor& color)
{
color_ = color;
update();
}Qt::Alignment LED::alignment() const
{
return alignment_;
}void LED::setAlignment(Qt::Alignment alignment)
{
alignment_ = alignment;update();
}
void LED::setFlashRate(int rate)
{
flashRate_ = rate;update();
}
void LED::setFlashing(bool flashing)
{
flashing_ = flashing;update();
}
void LED::startFlashing()
{
setFlashing(true);
}void LED::stopFlashing()
{
setFlashing(false);
}void LED::setState(bool state)
{
state_ = state;
update();
}void LED::toggleState()
{
state_ = !state_;
update();
}int LED::heightForWidth(int width) const
{
return width;
}QSize LED::sizeHint() const
{
return QSize(diamX_, diamY_);
}QSize LED::minimumSizeHint() const
{
return QSize(diamX_, diamY_);
}void LED::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);QPainter p(this); QRect geo = geometry(); int width = geo.width(); int height = geo.height(); int x=0, y=0; if ( alignment_ & Qt::AlignLeft ) x = 0; else if ( alignment_ & Qt::AlignRight ) x = width-diamX_; else if ( alignment_ & Qt::AlignHCenter ) x = (width-diamX_)/2; else if ( alignment_ & Qt::AlignJustify ) x = 0; if ( alignment_ & Qt::AlignTop ) y = 0; else if ( alignment_ & Qt::AlignBottom ) y = height-diamY_; else if ( alignment_ & Qt::AlignVCenter ) y = (height-diamY_)/2; QRadialGradient g(x+diamX_/2, y+diamY_/2, diamX_*0.4, diamX_*0.4, diamY_*0.4); g.setColorAt(0, Qt::white); if ( state_ ) g.setColorAt(1, color_); else g.setColorAt(1, Qt::black); QBrush brush(g); p.setPen(color_); p.setRenderHint(QPainter::Antialiasing, true); p.setBrush(brush); p.drawEllipse(x, y, diamX_-1, diamY_-1); if ( flashRate_ > 0 && flashing_ ) timer_->start(flashRate_); else timer_->stop();
}
bool LED::state() const
{
return state_;
}bool LED::isFlashing() const
{
return flashing_;
}int LED::flashRate() const
{
return flashRate_;
}tank.cpp (To build the tank and its slots)
#include "tank.h"
#include <QPainter>
#include <QPaintDevice>
#include<math.h>Tank::Tank(QWidget *parent) :
QWidget(parent),
Width(50),
halfHeight(25),
myColor(QColor("blue")), //default values
myLevel(12),
myAlignment(Qt::AlignCenter),
myUpperRange(50),
mylowerRange(0)
{
setLevel(myLevel);
}int Tank::width() const
{
return Width;
}void Tank::setWidth(int width)
{
Width = width;
update();
}int Tank::halfheight() const
{
return halfHeight;
}void Tank::sethalfHeight(int halfheight)
{
halfHeight = halfheight;
update();
}QColor Tank::color() const
{
return myColor;
}void Tank::setColor(QColor color)
{
myColor = color;
update();
}Qt::Alignment Tank::alignment() const
{
return myAlignment;
}void Tank::setAlignment(Qt::Alignment alignment)
{
myAlignment = alignment;
update();
}int Tank::upperRange() const
{
return myUpperRange;
}int Tank::lowerRange() const
{
return mylowerRange;
}void Tank::setlowerRange(int lower)
{
mylowerRange = lower;
update();
}void Tank::setupperRange(int upper)
{
myUpperRange = upper;
update();
}int Tank::heightForWidth(int width) const
{
return width;
}QSize Tank::sizeHint() const
{
return QSize(Width, halfHeight);
}QSize Tank::minimumSizeHint() const
{
return QSize(Width, halfHeight);
}void Tank::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);QRect geo = geometry(); int width = geo.width(); int height = geo.height(); int x=0, y=0; if ( myAlignment & Qt::AlignLeft ) x = 0; else if ( myAlignment & Qt::AlignRight ) x = width-(Width+(2*halfHeight)); else if ( myAlignment & Qt::AlignHCenter ) x = halfHeight+((+width-(Width+(2*halfHeight)))/2); else if ( myAlignment & Qt::AlignJustify ) x = 0; if ( myAlignment & Qt::AlignTop ) y = 0; else if ( myAlignment & Qt::AlignBottom ) y = height-(2*halfHeight); else if ( myAlignment & Qt::AlignVCenter ) y = (height-(2*halfHeight))/2; myX=x; myY=y; QPainterPath mainTank; mainTank.setFillRule(Qt::WindingFill); mainTank.addRect(myX,myY,Width,2*halfHeight); mainTank.addEllipse(QPointF(myX,(myY+halfHeight)),halfHeight,halfHeight); mainTank.addEllipse(QPointF(myX+Width,myY+halfHeight),halfHeight,halfHeight); QPainterPath fillTank; QPointF start((myX)-sqrt((halfHeight*halfHeight)-((halfHeight-myLevel)*(halfHeight-myLevel))),(myY)+(2*halfHeight)-myLevel); fillTank.moveTo(start); float theta1 = asin((float(halfHeight-myLevel)/float (halfHeight))); theta1 = (theta1*180)/3.142; theta1 = int(theta1); QRectF rect1((myX-halfHeight),myY,2*halfHeight,2*halfHeight); fillTank.arcTo(rect1,180+theta1,90-theta1); fillTank.lineTo((myX+Width),(myY+(2*halfHeight))); QRectF rect2((myX+Width-halfHeight),myY,2*halfHeight,2*halfHeight); fillTank.arcTo(rect2,270,90-theta1); fillTank.closeSubpath(); QPainter painter(this); painter.fillPath(mainTank,Qt::lightGray); painter.setRenderHint(QPainter::Antialiasing); painter.strokePath(mainTank.simplified(),QPen(Qt::black,1)); painter.strokePath(fillTank.simplified(),QPen(Qt::black,1)); painter.fillPath(fillTank,myColor);
}
void Tank::setLevel(int level)
{
myLevel = ((level-mylowerRange)2halfHeight)/(myUpperRange-mylowerRange);
update();
}And a mainwindow.ui file with just a tank and LED
Is there any problem with the .dll I exported to the plugins folder or with code of the plugin ?
-
Why do you have your plugins and application all in the same project ?