PDA

View Full Version : errors when using Q_OBJECT and slots



kja
13th November 2010, 01:47
Hi,
I'm new to qt programming and I'm trying to make some custom signals and slots but I keep getting errors when I try to do some simple examples.

I can get this program to run by commenting out Q_OBJECT, but if I leave it in i get errors, any idea why that is?



#include <QtGui>
#include <QApplication>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include "qobjectdefs.h"

class myCanvas : public QWidget{
Q_OBJECT //this program runs fine if i comment out Q_OBJECT
public:
myCanvas (QWidget * parent = 0);
public Q_SLOTS:
void copyText(const QString & text);
};

myCanvas::myCanvas(QWidget *parent):QWidget(parent){
QLineEdit * lineedit = new QLineEdit;
QPushButton * pushbutton = new QPushButton("Enter");

QVBoxLayout * layout = new QVBoxLayout;
layout->addWidget(lineedit);
layout->addWidget(pushbutton);
setLayout(layout);
}

int main (int argc, char * argv[])
{
QApplication app (argc, argv);
myCanvas bob;
bob.show();
return app.exec();
}

errors with Q_OBJECT uncommented:



1>Linking...
1>connectWorking.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall myCanvas::metaObject(void)const " (?metaObject@myCanvas@@UBEPBUQMetaObject@@XZ)
1>connectWorking.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall myCanvas::qt_metacast(char const *)" (?qt_metacast@myCanvas@@UAEPAXPBD@Z)
1>connectWorking.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall myCanvas::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@myCanvas@@UAEHW4Call@QMetaObject@@HP APAX@Z)
1>...\Debug\funcLoadData.exe : fatal error LNK1120: 3 unresolved externals
1>funcLoadData - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Timoteo
13th November 2010, 01:58
Looks like you didn't implement your copyText() slot.

kja
13th November 2010, 02:31
Thanks for the fast response.

I'm sorry if this is obvious, but even if i only put


class myCanvas : public QWidget{
Q_OBJECT
public:
myCanvas (QWidget * parent = 0);
};

and don't try to make my own slot, simply using a default slot like clear()

connect(pushbutton, SIGNAL(clicked()), lineedit, SLOT(clear()));

I still get the same three errors.

Are these errors coming because Q_OBJECT needs me to have my own slots or should it be able to exist in the class without any custom slots?

thanks

Timoteo
13th November 2010, 03:17
Hmm. Is all of your code in connectWorking.cpp? Moc has to see the slots declared in a header (with the Q_OBJECT macro in the class) in order for moc to generate the proper code.

kja
13th November 2010, 18:35
Yes I did have all of my code in connectWorking.cpp. So I moved it like you said and put the class with Q_OBJECT into a header file then included it in my .cpp but I still get those pesky three errors.

header file:




.cpp file:

[CODE]#include "slots.h"

myCanvas::myCanvas(QWidget *parent):QWidget(parent){
lineedit = new QLineEdit(this);
pushbutton = new QPushButton("Enter", this);

connect(pushbutton, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
QVBoxLayout * layout = new QVBoxLayout;
layout->addWidget(lineedit);
layout->addWidget(pushbutton);
setLayout(layout);
}
void myCanvas::slotButtonClicked()
{
QString theText = lineedit->text();
}

int main (int argc, char * argv[])
{
QApplication app (argc, argv);
myCanvas bob;
bob.show();
return app.exec();
}

Some additional information:
So now that I implemented my slot, if I comment out Q_OBJECT I get an error in the output window

"Object::connect: No such slot QWidget::slotButtonClicked() int c:\...\connectworking.cpp:114"

thanks for helping me out.

tbscope
13th November 2010, 18:50
Just use "public slots:" instead of "public Q_SLOTS:"
And clean the project completely and rebuild it.

kja
13th November 2010, 18:54
when I do that I what look like syntax errors:


public slots:
void slotButtonClicked();


1>------ Rebuild All started: Project: funcLoadData, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'funcLoadData', configuration 'Debug|Win32'
1>Compiling...
1>connectWorking.cpp
1>c:\...\slots.h(16) : error C2146: syntax error : missing ':' before identifier 'slots'
1>c:\...\slots.h(17) : error C2062: type 'void' unexpected
1>c:\...\slots.h(17) : error C2238: unexpected token(s) preceding ';'
1>c:\...\connectworking.cpp(120) : error C2039: 'slotButtonClicked' : is not a member of 'myCanvas'
1> c:\...slots.h(10) : see declaration of 'myCanvas'
1>c:\...\connectworking.cpp(122) : error C2065: 'lineedit' : undeclared identifier
1>c:\...\connectworking.cpp(122) : error C2227: left of '->text' must point to class/struct/union/generic type
1> type is ''unknown-type''
1>Build log was saved at "file://c:\...\BuildLog.htm"
1>funcLoadData - 6 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Timoteo
13th November 2010, 20:13
I just constructed a project out of your code, and it compiles, links and executes as expected. I did make some minor adjustments (some formatting and streamlining the includes for a bit faster build). Here's what I have:

#ifndef SLOTS_H
#define SLOTS_H

#include <QWidget>
class QLineEdit;
class QPushButton;

class myCanvas : public QWidget
{
Q_OBJECT
QLineEdit *lineedit;
QPushButton *pushbutton;
public:
myCanvas (QWidget * parent = 0);
public slots:
void slotButtonClicked();
};


#endif //SLOTS_H



/#include "slots.h"
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QApplication>
myCanvas::myCanvas(QWidget *parent):QWidget(parent){
lineedit = new QLineEdit(this);
pushbutton = new QPushButton("Enter", this);

connect(pushbutton, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
QVBoxLayout * layout = new QVBoxLayout;
layout->addWidget(lineedit);
layout->addWidget(pushbutton);
setLayout(layout);
}
void myCanvas::slotButtonClicked()
{
QString theText = lineedit->text();
}

int main (int argc, char * argv[])
{
QApplication app (argc, argv);
myCanvas bob;
bob.show();
return app.exec();
}

It worked before and after the alterations. What does your .pro look like?

TEMPLATE = app
CONFIG += qt
QT += gui

SOURCES += \
connect.cpp

HEADERS += \
slots.h

kja
15th November 2010, 21:23
my .pro file is the same as yours

TEMPLATE = app
CONFIG += qt
QT += gui

SOURCES += \
connectWorking.cpp

HEADERS += \
slots.h


I just don't understand why I get syntax errors when I try to declare public slots...

All of the examples that came with Qt use "public slots:" and Q_OBJECT and they all run fine. Could the problem have something to do with my project settings or something like that?

Thanks for all of your help

kja
16th November 2010, 01:23
Yea! I got it!

the problem was that my .moc file was not being generated because I didn't have the correct properties for my .h file.

I needed to edit the command line and additional dependencies.

Thanks for all your help Timoteo!