PDA

View Full Version : Why Qt can not find a public slot?



Alex Snet
12th April 2009, 19:07
Hi.
When I compile my application compiler says that it can't find two public slots.



Object::connect: No such slot QWidget::geometryClicked(Geometry*,QPoint) in src/mwnd.cpp:28
Object::connect: No such slot QWidget::mouseEventCoordinate(QMouseEvent*,QPointF ) in src/mwnd.cpp:46


All the slots are defined in header and are writed in cpp file.

This is the part of code where I connect SIGNAL in mc and l and SLOT in mwnd.


mc = new MapControl( mapMcSize );
mapadapter = new TileMapAdapter("robots.local", "/maps/maps/%1/%2/%3.png", 256, 0, 17);
l = new MapLayer("Custom Layer", mapadapter);
mc->addLayer(l);


27 - 28

connect(l, SIGNAL( geometryClicked(Geometry*,QPoint) ),
this, SLOT( geometryClicked(Geometry*,QPoint) ));


45-46

connect(mc,SIGNAL(mouseEventCoordinate(const QMouseEvent*,QPointF)),
this, SLOT(mouseEventCoordinate(QMouseEvent*,QPointF)));



Header:


public slots:
void geometryClicked(Geometry* geom, QPoint coord_px);
void mouseEventCoordinate(QMouseEvent* event,QPointF point);


CPP:


void mwnd::geometryClicked(Geometry *geom, QPoint)
{
if (geom->hasClickedPoints())
{
QList<Geometry*> pp = geom->clickedPoints();
for (int i=0; i<pp.size(); i++)
{
QMessageBox::information(this, geom->name(), pp.at(i)->name());
}
}
else if (geom->GeometryType == "Point")
{
QMessageBox::information(this, geom->name(), "just a point");
}
}
void mwnd::mouseEventCoordinate(QMouseEvent *event,QPointF point)
{
QMessageBox::information(this, "Test", QString("%1 : %2").arg(point.x()).arg(point.y()));
event->accept();
}


What's I does wrong? Where is my mistake?
(Sorry for bad english)

PS I used qmapcontrol http://www.medieninf.de/qmapcontrol/

aamer4yu
12th April 2009, 20:37
In what class/function are you making the connections ?
Have u used Q_OBJECT in ur class ?

talk2amulya
12th April 2009, 20:48
for some reason, Qt is trying to find the slot in QWidget instead of ur mwnd class


Object::connect: No such slot QWidget::geometryClicked(Geometry*,QPoint) in src/mwnd.cpp:28
Object::connect: No such slot QWidget::mouseEventCoordinate(QMouseEvent*,QPointF ) in src/mwnd.cpp:46

..does ur class have any such parenting? could you elaborate a bit on code of mwnd?

Alex Snet
12th April 2009, 20:54
#ifndef MWND_H
#define MWND_H

#include <QWidget>
#include <QSettings>
#include "./../maps/qmapcontrol.h"

#include "thblackbutton.h"
#include "thblackbar.h"

using namespace qmapcontrol;
class mwnd : public QWidget
{
public:
mwnd();
~mwnd();

MapControl* mc;
MapAdapter* mapadapter;

QPointF coord1;
QPointF coord2;

Layer* l;
void createMapControl();
// Settings
QSettings sets;

public slots:
void geometryClicked(Geometry* geom, QPoint coord_px);
void mouseEventCoordinate(QMouseEvent* event,QPointF point);

protected:
void resizeEvent(QResizeEvent *event);
void wheelEvent(QWheelEvent *event);
};

#endif // MWND_H



and cpp:


#include "mwnd.h"

mwnd::mwnd()
{
QSize mapMcSize = sets.value("/mwnd/size",QSize(800,600)).value<QSize>();
this->resize( mapMcSize );


QPoint mapMcPos = sets.value("/mwnd/pos",QPoint(100,100)).value<QPoint>();
this->move( mapMcPos );

mc = new MapControl( mapMcSize );
mc->showScale(true);
coord1 = QPointF();
coord2 = QPointF();

mapadapter = new TileMapAdapter("robots.local", "/maps/maps/%1/%2/%3.png", 256, 0, 17);

// create a layer with the mapadapter and type MapLayer
l = new MapLayer("Custom Layer", mapadapter);
mc->addLayer(l);

// Add the Points and the QPen to a LineString
LineString* ls = new LineString();
// Add the LineString to the layer
l->addGeometry(ls);
connect(l, SIGNAL( geometryClicked(Geometry*,QPoint) ),
this, SLOT( geometryClicked(Geometry*,QPoint) ));


// create buttons as controls for zoom
QPushButton* zoomin = new QPushButton("+");
QPushButton* zoomout = new QPushButton("-");
zoomin->setMaximumWidth(50);
zoomout->setMaximumWidth(50);
QSlider* zoomslider = new QSlider(Qt::Vertical,this);
zoomslider->setMaximum(17);
zoomslider->setMinimum(0);
zoomslider->setMaximumHeight( 170 );

connect(zoomin, SIGNAL(clicked(bool)), mc, SLOT(zoomIn()));
connect(zoomout, SIGNAL(clicked(bool)),mc, SLOT(zoomOut()));
connect(zoomslider, SIGNAL(valueChanged(int)), mc, SLOT(setZoom(int)));
connect(mc,SIGNAL(zoomChanged(int)), zoomslider, SLOT(setValue(int)));
connect(mc,SIGNAL(mouseEventCoordinate(const QMouseEvent*,QPointF)),
this, SLOT(mouseEventCoordinate(QMouseEvent*,QPointF)));


// add zoom buttons to the layout of the MapControl
QVBoxLayout* plusminusbtn = new QVBoxLayout;
plusminusbtn->addWidget(zoomin);
plusminusbtn->addWidget(zoomslider);
plusminusbtn->addWidget(zoomout);


// MapControl layout
QVBoxLayout* innerlayout = new QVBoxLayout;
innerlayout->addLayout(plusminusbtn);
mc->setLayout(innerlayout);

//mc->setView(QPointF(0.00656,0.01929));
// 55.809952,37.500973
//GPS_Position pos = GPS_Position(1234567890 ,37.500973,"W",55.809952,"N");
QPointF coord = sets.value("/mwnd/mc/pos",QPointF( 55.81 , 37.501 )).value<QPointF>();
mc->setView( coord );
int zoom = sets.value("/mwnd/mc/zoom", 15).value<int>();
mc->setZoom(zoom);

ls->addPoint( new CirclePoint( coord.x(), coord.y(),"Start location", Point::Middle) );


//QLabel* point;
//innerlayout->addWidget( point );
QTabWidget* tabs = new QTabWidget();
tabs->addTab(mc, "Map");
//layout->addWidget(mc);

QVBoxLayout* layout = new QVBoxLayout;
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
layout->addWidget( tabs );
this->setLayout(layout);

}
mwnd::~mwnd()
{
sets.setValue("/mwnd/size",this->size());
sets.setValue("/mwnd/pos",this->pos());
sets.setValue("/mwnd/mc/pos", mc->currentCoordinate() );
sets.setValue("/mwnd/mc/zoom",mc->currentZoom() );
}

// Protected methods
void mwnd::resizeEvent(QResizeEvent *event)
{
//mc->resize( (int) this->size().width(), (int) this->size().height() );
//qDebug( QString("W: %1 H: %2").arg(this->size().width()).arg(this->size().height()).toAscii() );
//mc->update();
event->accept();
//QWidget::resizeEvent(event);
}
void mwnd::wheelEvent(QWheelEvent *event)
{
int numDegrees = event->delta() / 8;
int numSteps = numDegrees / 15;

if (event->orientation() == Qt::Horizontal) {
// Change view
} else {
if(numSteps > 0)
{
if(mc->currentZoom()<17)
{
mc->zoomIn();
}
}
else
{
if(mc->currentZoom()>0)
{
mc->zoomOut();
}
}
}
event->accept();
}
void mwnd::geometryClicked(Geometry *geom, QPoint)
{
if (geom->hasClickedPoints())
{
QList<Geometry*> pp = geom->clickedPoints();
for (int i=0; i<pp.size(); i++)
{
QMessageBox::information(this, geom->name(), pp.at(i)->name());
}
}
else if (geom->GeometryType == "Point")
{
QMessageBox::information(this, geom->name(), "just a point");
}
}
void mwnd::mouseEventCoordinate(QMouseEvent *event,QPointF point)
{
QMessageBox::information(this, "Test", QString("%1 : %2").arg(point.x()).arg(point.y()));
event->accept();
}

drhex
12th April 2009, 21:34
You need the Q_OBJECT macro in the header of class mwnd.

Alex Snet
12th April 2009, 21:36
Sorry? Can you write a sample?

Alex Snet
12th April 2009, 21:38
Like this?

using namespace qmapcontrol;
class mwnd : public QWidget
{
Q_OBJECT
public:
mwnd(QWidget* parent = 0);
~mwnd();

If I write this - I recieve this:

:-1: error: collect2: ld returned 1 exit status

talk2amulya
12th April 2009, 22:10
can you post the whole error? this is just linker stopping cuz of some error that occured before

Alex Snet
12th April 2009, 23:55
Sorry, I don't understand.
I write all I have... Where is my bad?

spirit
13th April 2009, 06:47
you have to rebuild your app after adding Q_OBJECT macro.
so, do this


make/mingw32-make/nmake clean
qmake
make/mingw32-make/nmake

Alex Snet
13th April 2009, 08:18
Rebuilding and cleaning does not help =(

Why the compiler can not find the socket if it was declared?

spirit
13th April 2009, 08:20
can you attach compilable example?

Alex Snet
13th April 2009, 08:25
Problem is solved. Thank you!
It's realy my bad. When I cleaning up my project from terminal (qmake clean) some files are missed and doesn't deleted. And when I cleaning by myself - application start's normaly.

Lykurg
13th April 2009, 08:31
(qmake clean)
Typo? It has to be make clean!