[SOLVED] Qt Creator Widget plugin: strange linker error



  • Hello

    I have a widget library which rely on Qt 4.7 libraries. After upgrade to 4.8, I added a new widget to my library. When try to use it in an application, linker says there is no reference to constructor of widget (which I already implemented). All of old widgets are working properly.

    After upgrade to 4.8, I found that widget creation wizard of Qt Creator changed. QWidge subclasses no more have a ui instance and there is no Ui namespace and destructor by default. Instead they inherit from Ui::<widget_name>. The only difference between old widgets and newly added one is this. So I guess the problem is structure of class.

    How do solve the problem? If I have to convert my widget class to old style, I would like to know how.

    This is new widget:
    @
    #ifndef DATEQUERY_H
    #define DATEQUERY_H
    #include "ui_datequery.h"
    class DateQuery : public QWidget, private Ui::DateQuery // Different
    {
    Q_OBJECT
    Q_PROPERTY(QString format READ format WRITE setFormat USER true)
    public:
    DateQuery(QWidget *parent = 0);
    QString statement();
    QString format();
    public slots:
    void makeStatement();
    void setFieldName(QString);
    void setFormat(QString);
    signals:
    void fieldNameChanged(QString);
    void statementChanged(QString);
    void formatChanged(QString);
    private:
    QString fieldName;
    QString m_statement;
    QString m_format;
    };
    #endif // DATEQUERY_H
    @

    And this is the older one which works properly:
    @
    #ifndef NUMERICQUERY_H
    #define NUMERICQUERY_H

    #include <QWidget>
    // Different parts:
    namespace Ui {
    class NumericQuery;
    }
    class NumericQuery : public QWidget // Different part: there is no private inheritance from Ui class
    {
    Q_OBJECT
    Q_PROPERTY(double minimum READ min WRITE setMin USER true)
    Q_PROPERTY(double maximum READ max WRITE setMax USER true)
    Q_PROPERTY(int decimals READ decimals WRITE setDecimals USER true)
    public:
    explicit NumericQuery(QWidget *parent = 0);
    ~NumericQuery();
    QString statement();
    double min();
    double max();
    int decimals();
    public slots:
    void makeStatement();
    void setFieldName(QString);
    void setMin(double);
    void setMax(double);
    void setDecimals(int);
    signals:
    void fieldNameChanged(QString);
    void statementChanged(QString);
    private:
    Ui::NumericQuery *ui;
    QString fieldName;
    QString m_statement;
    double m_min;
    double m_max;
    int m_decimals;
    };
    #endif // NUMERICQUERY_H
    @



  • Hi.
    It would be helpful if you posted the actual linker error you get. But from what you wrote I think the implementation of the constructor is missing, so the problem probably is not in the header file. Do you link to the correct files?



  • This is error I get:
    @
    ./ui_mainwindow.h:132: undefined reference to `DateQuery::DateQuery(QWidget*)'
    collect2: ld returned 1 exit status
    @
    And implementation of constructor:
    @
    // datequery.cpp:
    DateQuery::DateQuery(QWidget *parent) :
    QWidget(parent)
    {
    setupUi(this);
    }
    @



  • [quote author="mkuettler" date="1337357139"]
    Do you link to the correct files?[/quote]

    Yes I think I'm linking corerctly. I do this:

    make project

    Close Qt Creator

    sudo make uninstall && sudo make install

    Copy header files to /usr/include/agt

    And in .pro file of application:
    @
    LIBS += -lagtplugin
    INCLUDEPATH += /usr/include/agt
    @



  • Are you sure datequery.cpp is included in the linking process?



  • Sorry, I didn't see your last post when I wrote mine. From what you write I can't tell if everything is correct, but it looks good to me. Still, the error message means that the linker cannot find the implementation of the constructor, and I assume the file is not visible to the linker. I cannot think of an other reason.



  • [quote author="soroush" date="1337357660"]
    And in .pro file of application:
    @
    LIBS += -lagtplugin
    INCLUDEPATH += /usr/include/agt
    @[/quote]

    I do not understand one thing: why do you need link to the "agtplugin"? It's really a plugin like your said in the thread title?



  • [quote author="1+1=2" date="1337358491"]
    [quote author="soroush" date="1337357660"]
    And in .pro file of application:
    @
    LIBS += -lagtplugin
    INCLUDEPATH += /usr/include/agt
    @[/quote]

    I do not understand one thing: why do you need link to the "agtplugin"? It's really a plugin like your said in the thread title?[/quote]

    Its a widget library. I removed LIBS += -lagtplugin and got 8 linker errors (for all 8 widgets I put on my main window)



  • Oh, I see, what you really mean is a normal shared library instead of a plugin.

    If I am right. what you are doing is:

    • Changed source code of a library(By adding a new class)
    • Rebuild the library
    • Install it (Wait... In which place you install it ?)
    • Copy header files (Doesn't this done in last step?)
    • Using your library by LIBS and INCLUDEPATH (Wait... are your sure LIBS += -lagtplugin linked to your new build library?)

    By the way, whether the QtCreator generated code inherit from Ui::<widget_name> or not depends on youself. Please go to "Tools/Options/Designer/..."

    Debao



  • [quote author="1+1=2" date="1337366955"]
    By the way, whether the QtCreator generated code inherit from Ui::<widget_name> or not depends on youself. Please go to "Tools/Options/Designer/..."
    [/quote]

    Oh! Thank you! I didn't know that :)

    bq. Install it (Wait… In which place you install it ?)

    Makefile installs it on /usr/lib/x86_64-linux-gnu/qt4/plugins/designer/libagtplugin.so . After sudo make install I can see widgets in Qt Creator.

    bq. Copy header files (Doesn’t this done in last step?)

    I think it's not done by build system. I have to copy headers in /usr/include or somewhere else and let other projects know about their location. Am I doing it wrong?

    bq. are your sure LIBS += -lagtplugin linked to your new build library?

    Removing library by sudo make uninstall. Output is like:
    rm -f "/usr/lib/x86_64-linux-gnu/qt4/plugins/designer/libagtplugin.so"
    So I can say, yes I'm sure.



  • ;-( I am really confused by what you are doing now.

    bq. Makefile installs it on /usr/lib/x86_64-linux-gnu/qt4/plugins/designer/libagtplugin.so . After sudo make install I can see widgets in Qt Creator.

    Ok, you really build a plugin for designer. but this plugin doesn't intent to be used by application.

    Though you can use it as a normal shared library in your application if you export symbols properly, but it is not encouraged.

    Normally, you need to build a shared library, which can be used by your application, or optionally by your designer plugin.

    bq. I think it’s not done by build system. I have to copy headers in /usr/include or somewhere else and let other projects know about their location. Am I doing it wrong?

    Which files need to be installed, and where to install them , all controlled by yourself. look your xxx.pro files carefully if it is not written by yourself manually.

    bq. Removing library by sudo make uninstall. Output is like:
    rm -f “/usr/lib/x86_64-linux-gnu/qt4/plugins/designer/libagtplugin.so”
    So I can say, yes I’m sure.

    No, You still don't give evidence that this is the library to be linked by your linker.



  • [quote author="1+1=2" date="1337370924"]
    No, You still don't give evidence that this is the library to be linked by your linker.[/quote]

    This is a part of output of ldd ./cards-report (the application that uses widget library)
    @
    ....
    /usr/lib/x86_64-linux-gnu/qt4/plugins/designer/libagtplugin.so (0x00007f0b17c0d000)
    ....
    @



  • Ahhh... Finally!
    Projects, have to be rebuilt after any changes applied to any of libraries they linked against. Though I thought this is only true for statically linked libraries...
    I learned this today :)


Log in to reply
 

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