PDA

View Full Version : What do I do wrong



Arif Bilgin
20th October 2010, 19:16
Hi Everybody,
Can someone tell me what is wrong with the code below.All I want to do is connecting an action to a slot which is defined in a derived class.

I get the following error message saying QMainWindow doesnt have such a slot but code uses a derived class(SMainWindow) which has the rewuired slot.

Object::connect: No such slot QMainWindow::slotNewGraph() in c:\qt_test\main.cpp:26
Object::connect: (sender name: 'actionNew')
Object::connect: (receiver name: 'MainWindow')





#include "QApplication.h"
#include "mainactions.h"
class SMainWindow : public QMainWindow
{
private slots:
void slotNewGraph()
{
printf("new Graph\n");
}
};

int main(int argc, char** argv)
{

QApplication app(argc,argv);

Ui::MainWindow ui;
SMainWindow* mainForm=new SMainWindow;
ui.setupUi(mainForm);

QAction* actionNew = mainForm->findChild<QAction*>("actionNew");
QObject::connect(actionNew, SIGNAL(activated()), mainForm, SLOT(slotNewGraph()));

mainForm->show();
return app.exec();
return 0;
}

Thanks in advance!

Timoteo
20th October 2010, 19:37
MOC needs to see a slot defined in a header in order to generate the necessary code for it.

Edit: spelling error.:cool:

jonthom
20th October 2010, 19:39
At least 1 problem is that you need the Q_OBJECT macro in your class definition.


class SMainWindow : public QMainWindow {
Q_OBJECT
private slots:
void slotNewGraph() { printf("new Graph\n"); }
};

Arif Bilgin
20th October 2010, 19:40
u mean just add a
#define SLOT 1 somewhere in the code?

Timoteo
20th October 2010, 19:42
No, the header for your class. it appears to me in the code that you posted that you are defining the class inline in your main source. If this isn't the case, then post more complete code.

Arif Bilgin
20th October 2010, 19:43
i did the Q_OBJECT trick
now I get unresolved symbols. Any Ideas?

error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall SMainWindow::metaObject(void)const " (?metaObject@SMainWindow@@UBEPBUQMetaObject@@XZ)
error LNK2001: unresolved external symbol "public: virtual void * __thiscall SMainWindow::qt_metacast(char const *)" (?qt_metacast@SMainWindow@@UAEPAXPBD@Z)
error LNK2001: unresolved external symbol "public: virtual int __thiscall SMainWindow::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@SMainWindow@@UAEHW4Call@QMetaObject@ @HPAPAX@Z)
fatal error LNK1120: 3 unresolved externals

it is just a test code ,yes an inline class.This is the whole thing + ui header which is automatically genereated

wysota
20th October 2010, 19:45
No, it means add the Q_OBJECT macro to your class and rerun qmake.

Timoteo
20th October 2010, 19:47
Inline definitions are (not fine, but permissible) in headers, but simply won't work right with Qt's signal/slot mechanism when defining new slots and defining the class inline in a cpp. MOC needs to see the slot declaration (I originally said "definition" but I am reversing myself but that isn't quite right) in a header.

Edit: lost train of though.:cool:

Arif Bilgin
20th October 2010, 20:03
I moved the class definition to a seperate header file , and added Q_OBJECT macro. here is how the code looks like now.
And I still get the unresolved symbols


error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall SMainWindow::metaObject(void)const " (?metaObject@SMainWindow@@UBEPBUQMetaObject@@XZ)
error LNK2001: unresolved external symbol "public: virtual void * __thiscall SMainWindow::qt_metacast(char const *)" (?qt_metacast@SMainWindow@@UAEPAXPBD@Z)
error LNK2001: unresolved external symbol "public: virtual int __thiscall SMainWindow::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@SMainWindow@@UAEHW4Call@QMetaObject@ @HPAPAX@Z)
fatal error LNK1120: 3 unresolved externals



smainwindow.h


#pragma once

#include "QApplication.h"
#include "QMainWindow.h"
class SMainWindow:public QMainWindow
{
Q_OBJECT
private slots:
void slotNewGraph();
};

smainwindow.cpp


#include "smainwindow.h"

void SMainWindow::slotNewGraph()
{
printf ("new Graph\n");
}


main.cpp


#include "QApplication.h"
#include "frmmain.h"
#include "smainwindow.h"
int _tmain(int argc, char** argv)
{

QApplication app(argc,argv);

Ui::MainWindow ui;
SMainWindow* mainForm=new SMainWindow;
ui.setupUi(mainForm);

QAction* actionNew = mainForm->findChild<QAction*>("actionNew");
QObject::connect(actionNew, SIGNAL(activated()), mainForm, SLOT(slotNewGraph()));

mainForm->show();
return app.exec();
return 0;
}

P.S frmmain.h is a qt designer generated header.

wysota
20th October 2010, 20:05
Let me repeat myself - add the Q_OBJECT macro and rerun qmake.

Arif Bilgin
20th October 2010, 20:08
wysote,

I use vs2008 as compiler and Q_OBJECT is in the SMainWindow class definition.

Thanks,

I think it is about MOC ing , whatever it is. I need to do more readings.
Thanks guys.

Problem is solved. If you work with visual studio any class that is derived from a QT class has to be moced. then output of the moc operation should be added to cpp file of the derived class (not in header)
how moc a header
1) Add qt bin directory to your path
2)Open cmd and cd to the location of the header
3)moc header.h > header.cpp
4)work on your new header.cpp

wysota
20th October 2010, 20:25
If you work with visual studio any class that is derived from a QT class has to be moced.
No, that's not true.


how moc a header
1) Add qt bin directory to your path
2)Open cmd and cd to the location of the header
3)moc header.h > header.cpp
4)work on your new header.cpp
Or run "qmake -project" and then "qmake -tp vc" when you start developing a project. Then Visual Studio will be mocing files for you by itself.

Arif Bilgin
20th October 2010, 21:03
wysote,
you are absolutely right !
These are the steps to automate all mocing and .ui to .h conversion
1-)Make sure QT Add in for Visual Studio is installed
2-)Create a a qt project with qmake
qmake -project
qmake myproject.pro


3-)Open Visual Studio | Click on QT menu | Open Qt Project File

and you are all set , all mocings and uic ings are taken care automatically by QT add in.

Beautiful!