Important: Please read the Qt Code of Conduct -

[SOLVED] undefined reference to signal in resizeEvent()

  • Since widgets in Qt don't have a resize signal I thought I'd use the resizeEvent() slot to emit a signal of my own. However, during compilation I keep getting undefined reference to mwid::mySizeChanged(int, int)'_ error messages and I don't understand why. I know the issue has something to do with the MOC, but I cleaned the project with make distclean, and I also run qmake manually and rebuilt over and over, it doesn't work. Adding the Q_OBJECT macro simply creates _undefined reference tovtable for mwid' errors, so I guess it's not needed.
    Strange thing is that this only happens in the resizeEvent() slot. If I create a slot of my own and emit the signal, it works just fine. Also, the code compiles fine if I don't emit that signal in resizeEvent().

    Next there is the code I'm using. It's some boilerplate code, so please don't expect much. The project .pro file uses core, gui and widgets modules and c++11 CONFIG.
    I hope you can help me...

    #include <QApplication>
    #include <QWidget>
    #include <QResizeEvent>
    #include "ExtDebug.h"

    class mwid : public QWidget{
    // the Q_OBJECT macro creates "undefined reference to vtable" errors
    // Q_OBJECT
    void mySizeChanged(int width, int height);

    public slots:
    void resizeEvent(QResizeEvent * ev){
    // if you remove next line, the rest of the code works just fine
    emit mySizeChanged(300, 200);

    int main(int argc, char *argv[]){
    QApplication app(argc, argv);

    mwid * mainWin = new mwid;
    mainWin->setMinimumSize(320, 240);
    ExtDebug * dbgWin = new ExtDebug(mainWin);

    mainWin->connect(mainWin, SIGNAL(mySizeChanged(int,int)),
    dbgWin, SLOT(resize(int,int)));


    int ret = app.exec();

    delete mainWin;
    mainWin = nullptr;
    dbgWin = nullptr;

    return ret;

    #ifndef EXTDEBUG_H
    #define EXTDEBUG_H

    #include <QObject>
    #include <QWidget>
    #include <QLineEdit>
    #include <QTextEdit>

    class ExtDebug : public QObject{

    QTextEdit * output;
    QLineEdit * input;

    ExtDebug(QWidget * parent);

    public slots:
    void resize(int width, int height);

    #endif // EXTDEBUG_H

    #include "ExtDebug.h"

    ExtDebug::ExtDebug(QWidget * parent){
    output = new QTextEdit(parent);
    output->setMinimumHeight(parent->minimumHeight() - 20);

    input = new QLineEdit(parent);
    input->move(0, output->height());

    delete input;
    delete output;

    input = nullptr;
    output = nullptr;

    void ExtDebug::resize(int width, int height){
    output->resize(width, height - 20);

    input->resize(width, 20);
    input->move(0, height);

  • Moderators

    [quote author="T3STY" date="1423993404"]Adding the Q_OBJECT macro simply creates undefined reference to `vtable for mwid' errors, so I guess it's not needed.[/quote]Yes, the Q_OBJECT macro is needed for every class that uses signals and slots.

    [quote author="T3STY" date="1423993404"]
    class mwid : public QWidget{
    [/quote]qmake expects your classes to be in .h files, not .cpp files. Move your class definition from main.cpp to a .h file. Otherwise, moc will not process your class.

    In general, to get rid of the vtable error, run qmake manually after you add the Q_OBJECT macro to your class (in a .h file).

  • I've got it working, thank you very much for help :)

    Just a side note: when using the Q_OBJECT macro the public, private and protected keywords must be put after the Q_OBJECT declaration. Otherwise the Q_OBJECT macro will leave some private or protected keyword behind it and some "class xx is private within this context" errors may appear.

Log in to reply