[Qgis-developer] not able to downCast to Custom class

nitin quick quick.nitin at gmail.com
Tue Nov 14 06:13:59 EST 2006


greetings,
I know this doubt is more of C++ but i am out of sources and it
involves a lot of QGis classes.
Scenario is such:
I have custom canvas element class MyMapCanvasItem ,child of QgsMapCanvasItem.
A tool , MapCanvasTool , child of QgsMapTool. These are implemeted in
different plugins. One plugins accepts pouints from a pipe and display
on map background.
MapCanvasTool plugin is intended to do operation on these canvas
items, such that changing shape and color.

I am able to get mousePressEvents over custom canvas item. In
CanvasMousePressEvent() i am checking for collision of objects. So i
am having a list of Q3CanvasItems.
By checking their rtti() i know which class object it is and depending
on that i am making menu and signal-slot connection.
Hard part for me comes now. For doing any operation over the canvas
elements, i need a refrence to respective one in that slot. So i am
having a member pointer for refring to that.
Since on collision i am getting a list of Q3CanvasItem objects, i need
to downCast it to my class MyMapCanvasItem, but it returns null. I am
using dynamic_cast for that. This cast is happening perfectly for
QgsMapCanvasItem. Is there any way, i can avoid downcast  in such
scenarion???Also, is this way of doing peration is correct, as it look
to me since i have no control over QgsMapCanvasItem.

here is souce code::
//  my custom tool
class MapCanvasTool: public QObject,public QgsMapTool
{
	Q_OBJECT;
public:
	...........
	//!overidden functions for mouse movements and events
	virtual void canvasPressEvent(QMouseEvent *e);
......
	virtual bool isZoomTool() {	return false;}
// signals:
// 	void pointAdded(QgsPoint pt);
public slots:
	void changeColor();
..................
private:
	//PointMarker *mPointMarker;
	QgsMapCanvas *mCanvas;
	QgsMapCanvasItem *select;
	MyMapCanvasItem *item;

}	;

--------------------------------------------------------------------------------------------------
//IMPLEMENTATION



void MapCanvasTool::canvasPressEvent(QMouseEvent *e)
{	
	Q3CanvasItemList il = mCanvas->canvas()->collisions( e->pos() );
	if(e->button()==Qt::RightButton)//check for right button press
	{
		for( Q3CanvasItemList::Iterator it=il.begin(); it!=il.end(); ++it )      {
       		
			if((*it)->rtti()==12345)
			{	
			//	if(select=dynamic_cast<QgsMapCanvasItem *>(*it))
				//	QMessageBox::information(mCanvas,tr("Hello"),tr("Safe select
downcast "));//this is happening well


				//selection of item for doing operations over that
			if(!(item=dynamic_cast<MyMapCanvasItem *>(*it)))	{ //cast fails here
				QMessageBox::information(mCanvas,tr("Hello"),tr("Coudn't downcast "));
				break;
			}
			else{
				QMessageBox::information(mCanvas,tr("Hello"),tr("Safe downcast "));
				qWarning("\n%d ",select->rtti());
				}


			QMenu mn(mCanvas);
			
			//mn.addAction(abc);
			//adding a submenu
			QMenu *subMenu=mn.addMenu("Colors");
			subMenu->addAction("Make Red",this,SLOT(makeRed()));
			subMenu->addAction("Make Blue",this,SLOT(makeBlue()));
			subMenu->addAction("Make Aqua",this,SLOT(makeYellow()));
			//mn.addMenu(&subMenu);
			
			//mn.addAction(tr("Change Color"),this,SLOT(changeColor()));
			mn.exec(e->globalPos());
			}
			else
				std::cout<<"@! "<<(*it)->rtti()<<" ";
		
		}
}
}

--------------------------------------------------______________________________________
//CODE FOR CUSTOM OBJECT


class MyMapCanvasItem: public QgsMapCanvasItem
{
public:	
	MyMapCanvasItem(int i,int x, int y, QgsMapCanvas
*canvas):QgsMapCanvasItem(canvas),mCanvas(canvas),id(i),mX(x),mY(y)
	{	
		//updateCanvas();
		setBrush(Qt::red);
		mColor=1;
	};
		
		
	

	void setX(int x){	mX=x;	updatePosition(); updateCanvas();}
	void setY(int y){	mY=y;	updatePosition();updateCanvas();}
	void setColor(int i)	{	mColor=i;	updatePosition();updateCanvas();}
	void setPt(QPoint pt){	mX=pt.x(), mY=pt.y();	updatePosition();updateCanvas();}
	int myId(){ return id;}
	int whatX(){ return mX;}
	int whatY(){ return mY;}
	int whatIFF() {return mColor;}
	virtual int rtti() const {	return 12345 ;}
	
	void setRect(const QgsRect &r)
	{	mRect=r;
		updatePosition();
  		updateCanvas();	
	}
	QgsRect rect(){ return mRect;}

	bool operator==(MyMapCanvasItem *pl)
	{
		if(this->id==pl->id)
			return true;		
		else
			return false;
	}


	virtual void drawShape(QPainter &p)
	{	std::cout<<"|"<<mX<<" "<<mY;
		QBrush brush(Qt::blue);
		if(mColor==0)
		{	p.save();
			p.setBrush(brush);
			p.drawEllipse(QRect(mX-3,mY-3,6,6));
			p.drawLine(mX,mY,mX,mY-10);
			p.restore();
		}
		else if (mColor==1)
		{	brush.setColor(Qt::red);
			p.save();
			p.setBrush(brush);
			p.drawEllipse(QRect(mX-3,mY-3,6,6));
			p.drawLine(mX,mY,mX,mY-10);
			p.restore();
		}
		else if(mColor==2)	
		{	brush.setColor(Qt::yellow);
			p.save();
			p.setBrush(brush);
			p.drawEllipse(QRect(mX-3,mY-3,6,6));
			p.drawLine(mX,mY,mX,mY-10);
			p.restore();
		}
		//updateCanvas();
	}
protected:	
	void updatePosition()
	{
		move(mX,mY);
		setSize(10,10);
		show();
	}
	


private:
	int mX;
	int mY;
	int id;
	int mColor;
	QgsRect mRect;
	QgsMapCanvas *mCanvas;
	
};

#endif


i have spnt quite good time on that but beared no fruit.
I am looking for all knid of comments here on what i have done wrong.

regards
quickNitin



More information about the Qgis-developer mailing list