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 ofqt_plugin_query_metadata'
    moc_LEDPlugin.o:moc_LEDPlugin.cpp:(.text+0x30): first defined here
    moc_tankplugin.o: In function qt_plugin_instance': moc_tankplugin.cpp:(.text+0x40): multiple definition ofqt_plugin_instance'
    moc_LEDPlugin.o:moc_LEDPlugin.cpp:(.text+0x40): first defined here
    collect2: error: ld returned 1 exit status

    tankplugin.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 >= 0x050000

    public:
    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")
    #endif

    public:
    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


  • Lifetime Qt Champion

    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 gui

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    TARGET = untitled2
    TEMPLATE = app
    DEFINES += QT_DEPRECATED_WARNINGS

    SOURCES +=
    main.cpp
    mainwindow.cpp
    LED.cpp
    LEDPlugin.cpp

    HEADERS +=
    mainwindow.h
    LED.h
    LEDPlugin.h

    FORMS +=
    mainwindow.ui

    mainwindow.h (Automatically generated)
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QtWidgets/QMainWindow>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    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_OBJECT

    Q_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_OBJECT

    Q_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)
    #endif

    tankplugin.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 >= 0x050000

    public:
    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 ?


  • Lifetime Qt Champion

    Why do you have your plugins and application all in the same project ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.