PDA

View Full Version : How to find out the type of the clicked item..



Kapil
30th March 2006, 10:39
Hi..

I have mutiple items drawn on the canvas... they are either line or rectangles..
I want to find out which exact item i have clicked on... ie i item on which i have clicked is line or rect.. how do i find that out...

Thanking you,
Kapil

munna
30th March 2006, 10:58
The following functions will help you with your task

Q3CanvasItemList collisions ( const QPoint & p ) const (in Q3Canvas)
virtual int rtti () const (in Q3CanvasItem)

Kapil
30th March 2006, 11:09
The following functions will help you with your task

Q3CanvasItemList collisions ( const QPoint & p ) const (in Q3Canvas)
virtual int rtti () const (in Q3CanvasItem)

Hi..

Thanks..

Yaa true.. they will help me in finding out the item i have clicked on...

But i have 10 Line objects and 20 rectangle object.. Now of them whcih Line object has been clicked or which of the Rectangle object has been clicked is my question...

ie is it the 3rd line or the 5th.. or it is the 3rd rect or the 8th... How to retrieve this specific info.. do i have to write my own functions that would reduce to find out the information..

Kapil

munna
30th March 2006, 11:15
In that case you can maintain a list of items for comparision. You can have a list of all the lines, a list of all the rectangles and so on... Once you get the item that was selected or clicked, first find out if it was a line or rectangle.. and then compare the selected item with the appropriate list items to find out which line or rectangle was selected.

Hope you understood!!

Kapil
30th March 2006, 11:19
In that case you can maintain a list of items for comparision. You can have a list of all the lines, a list of all the rectangles and so on... Once you get the item that was selected or clicked, first find out if it was a line or rectangle.. and then compare the selected item with the appropriate list items to find out which line or rectangle was selected.

Hope you understood!!

Thanks a lot...:)

About my understanding :D i would just let you know what i deduced ->

I would have to maintain a list wherein i would have to keep the entire information of lines and rectangles and their exact locations... and whereever i have clicked, i would have to find the position and compare it with the line or rect location..

Is it what u wanted to say..

what are the other ways in which comparisons can be made ???? :confused:

munna
30th March 2006, 12:09
I would have to maintain a list wherein i would have to keep the entire information of lines and rectangles and their exact locations...

you just have to maintain a list of pointers of your items. Their locations are not needed.

Kapil
30th March 2006, 12:20
you just have to maintain a list of pointers of your items. Their locations are not needed.

Hi...

Yaa i have done that... i have the list of all the line and rect pointers with me...
But how will i know that the item i have clicked on is the "nth" line or "nth" rectangle....

can u give me some example or few lines of code that explains the thing...

it would be really very helpful for me...

Thanking you...

Kapil

munna
30th March 2006, 13:02
ok here it is




QList<Q3CanvasItem *> lineList;
QList<Q3CanvasItem *> rectList;

Q3CanvasItem *l = new Q3CanvasLine(yourCanvas);
lineList.append(l);

//Similarly Build your rectangle list;


Now to find which line was clicked



Q3CanvasItem* item;
// Find an item, e.g. with Q3CanvasItem::collisions().
...
if (item->rtti() == Rtti_Line) {
for(int i = 0; i< lineList.size(); ++i){
if(lineList.at(i) == item){
//Here you know that you have clicked the line which in the list is at i th location
}
}
}



Hope this helps

Kapil
30th March 2006, 14:01
Hi...

yaa i got the basic idea..
what i have done is this now:

First the creation of the Line List:


QList<Q3CanvasItem *> lineList;

Q3CanvasItem **l;
l = new Q3CanvasLine*[numLines]; //numLines is the number of lines on Canvas.
for(i=0;i<numLines;i++)
{
l[i] = new Q3CanvasLine(yourCanvas);
l[i] = canvasLine[i];
lineList.append(l[i]);
}

Same for the Rectangle;


Is it correct...

munna
30th March 2006, 14:20
In your code you are actually having two list. One in the form of QList and the other as array. This is not required. One is enough to perform the task.

Cheers

Kapil
30th March 2006, 14:25
In your code you are actually having two list. One in the form of QList and the other as array. This is not required. One is enough to perform the task.

Cheers

which means this:



QList<Q3CanvasItem *> lineList;

Q3CanvasItem *l = new Q3CanvasLine(yourCanvas);
l[i] = canvasLine[i];
lineList.append(l[i]);



is this what you were saying :confused:

Also the line lineList.at(i) == m_itemLine is giving error...

Its giving the comparison error as m_itemList is not a pointer object whereas the other one is... creating m_itemLine pointer creates problem with the collision statement as it return a non-pointer object value...

munna
30th March 2006, 14:44
QList<Q3CanvasItem *> lineList;
Q3CanvasItem *l = new Q3CanvasLine(yourCanvas);
l[i] = canvasLine[i];//WHAT IS THIS LINE FOR ????
lineList.append(l[i]); //This should be lineList.append(l);


collisions() returns a list. This means that to compare you need to do something like




lineList.at(i) == colList.at(j)

Kapil
30th March 2006, 14:47
still gives error and this is what it says..




error: no match for 'operator==' in '(((QList<Q3CanvasItem*>*)
((ImageDraw*)this)) + 56u)->QList<T>::at [with T = Q3CanvasItem*](i) == Q3ValueL
ist<T>::at(typename QLinkedList<T>::size_type) [with T = Q3CanvasItem*](i)'

munna
30th March 2006, 14:56
Can you paste your code ?

Kapil
31st March 2006, 04:50
Yaa..

Here is the code:

CanvasMouse.cpp This file handles the mouse click events and then finds the point through the collision method and sends the info to the ImageDraw class..


#include "canvasmouse.h"
CanvasMouse::CanvasMouse(Q3Canvas *pCanvas, QFrame *frame): Q3CanvasView(frame)
{
m_pCanvas = pCanvas;
Q3CanvasView::setCanvas(m_pCanvas);
m_pCanvas->setBackgroundColor(Qt::white);
m_pCanvas->resize(400, 400);
imgdraw = new ImageDraw(m_pCanvas);
setDraw = false;
startDraw = false;

}

CanvasMouse::~CanvasMouse()
{
}

void CanvasMouse::contentsMousePressEvent(QMouseEvent* e)
{
if(setDraw)
{
if(e->button() == Qt::LeftButton)
{
pPress = inverseWorldMatrix().map(e->pos());
startDraw = true;
}
}

}
void CanvasMouse::contentsMouseReleaseEvent(QMouseEvent * e)
{

if(setDraw)
{
if((e->button() == Qt::LeftButton) && startDraw)
{
pRelease = inverseWorldMatrix().map(e->pos());
Q3CanvasItemList l = m_pCanvas->collisions(pRelease);;

imgdraw->selectLine(l);
}
}
}



ImageDraw.cpp [B]: This class does the finding of the line number and rect number. Its the [B]selectLine function that finds the line number.



#include "imagedraw.h"
#include <Q3ValueList>

ImageDraw::ImageDraw(Q3Canvas *pCanvas): m_pCanvas(pCanvas)
{
drawLine();
drawRectangle();
}
ImageDraw::~ImageDraw()
{
}
void ImageDraw::drawLine()
{
int i;
int xxPoint = 2,xyPoint = 2,yxPoint = 202,yyPoint = 2;
lineNum = 20;
m_pCanvasLine = new Q3CanvasLine*[lineNum];
for(i=0;i<lineNum;i++)
{
xyPoint = (i+1)*4;
yyPoint = xyPoint;
m_pCanvasLine[i] = new Q3CanvasLine(m_pCanvas);
m_pCanvasLine[i]->setPoints(xxPoint,xyPoint,yxPoint,yyPoint);
m_pCanvasLine[i]->show();

}

m_pLineItem = new Q3CanvasLine(m_pCanvas);
lineList.append(m_pLineItem);

}

void ImageDraw::drawRectangle()
{
int xPoint = 4, yPoint = 100;
int height = 50, width = 80;
int i;
recNum = 5;
m_pCanvasRectangle = new Q3CanvasRectangle*[recNum];
for(i=0;i<recNum;i++)
{
m_pCanvasRectangle[i] = new Q3CanvasRectangle(xPoint, yPoint, width, height, m_pCanvas);
m_pCanvasRectangle[i]->show();
yPoint += 75;
}

}

void ImageDraw::selectLine(Q3CanvasItemList item)
{
int i=0;
m_itemLine = item;
for (Q3CanvasItemList::Iterator it= m_itemLine.begin(); it!= m_itemLine.end(); ++it)
{
if ( (*it)->rtti() == 7 )
{
for(i=0;i<lineList.size();i++)
{
if(lineList.at(i) == m_itemLine.at(i))
{

QMessageBox::information(this, tr("Mouse Event"),tr("Line %1 Mouse Event Handled ").arg(i));

}

}
}
else if ( (*it)->rtti() == 5 )
{
QMessageBox::information(this, tr("Mouse Event"),tr("Rectangle Mouse Event Handled "));
}
}
}



ImageDraw.h: The header file where i have made the dec.


#ifndef IMAGEDRAW_H
#define IMAGEDRAW_H

#include <QtGui>
#include <Q3Canvas>
#include <qdir.h>
#include <QColor>
#include <Q3CanvasLine>
#include <qevent.h>
#include <QPoint>
#include <Q3CanvasView>
#include <Q3ScrollView>
#include <Q3CanvasItem>
#include <Q3CanvasItemList>
#include <QPen>
#include <QList>

class ImageDraw : public Q3CanvasView
{
public:
ImageDraw(Q3Canvas *pCanvas);
~ImageDraw();
void drawLine();
void drawRectangle();
void selectLine(Q3CanvasItemList item);
//void selectRect(Q3CanvasItemList item);

private:
Q3Canvas *m_pCanvas;
Q3CanvasLine **m_pCanvasLine;
Q3CanvasRectangle **m_pCanvasRectangle;
Q3CanvasItemList m_itemLine;
Q3CanvasItemList m_itemRect;
QList<Q3CanvasItem *> lineList;
Q3CanvasItem *m_pLineItem;
//const QPoint m_pointLine,m_pointRect;
int lineNum;
int recNum;
bool lineDraw,rectDraw;
};

#endif



Please tell me what can be the problem...

Kapil
31st March 2006, 05:52
Hi munna...

Thanks a lot for ur suggestions..

I used the function collidesWith(lineList.at(i)) and it gave me the value of the line i have clicked on...

Also i was able to create the lineList ..

One doubt... How can I colour the created line with some other colour..

Using the pen, we create a line with another coloue but is there any function like stColour for the line which could set the lines colour to the one i need..

Thanking you,
Kapil

munna
31st March 2006, 05:53
Please Explain the following lines.




m_pCanvasLine = new Q3CanvasLine*[lineNum];
for(i=0;i<lineNum;i++) {
xyPoint = (i+1)*4;
yyPoint = xyPoint;
m_pCanvasLine[i] = new Q3CanvasLine(m_pCanvas);
m_pCanvasLine[i]->setPoints(xxPoint,xyPoint,yxPoint,yyPoint);
m_pCanvasLine[i]->show();
}
m_pLineItem = new Q3CanvasLine(m_pCanvas);
lineList.append(m_pLineItem);



and




m_pCanvasRectangle = new Q3CanvasRectangle*[recNum];
for(i=0;i<recNum;i++){
m_pCanvasRectangle[i] = new Q3CanvasRectangle(xPoint, yPoint, width, height, _pCanvas);
m_pCanvasRectangle[i]->show();
yPoint += 75;
}



As i said earlier you dont need to maintain two lists. One list should be more than enough to achieve your task. Please try to find out what exactly you need to achieve and what you are doing in your code.

Kapil
31st March 2006, 05:57
Please Explain the following lines.




m_pCanvasLine = new Q3CanvasLine*[lineNum];
for(i=0;i<lineNum;i++) {
xyPoint = (i+1)*4;
yyPoint = xyPoint;
m_pCanvasLine[i] = new Q3CanvasLine(m_pCanvas);
m_pCanvasLine[i]->setPoints(xxPoint,xyPoint,yxPoint,yyPoint);
m_pCanvasLine[i]->show();
}
m_pLineItem = new Q3CanvasLine(m_pCanvas);
lineList.append(m_pLineItem);



and




m_pCanvasRectangle = new Q3CanvasRectangle*[recNum];
for(i=0;i<recNum;i++){
m_pCanvasRectangle[i] = new Q3CanvasRectangle(xPoint, yPoint, width, height, _pCanvas);
m_pCanvasRectangle[i]->show();
yPoint += 75;
}



As i said earlier you dont need to maintain two lists. One list should be more than enough to achieve your task. Please try to find out what exactly you need to achieve and what you are doing in your code.


Hi.. yaa i understood it.. i was doing this mistake.. i after that removed the array and just maintained the QList as you had told me too.. also i was able to view the line number as i told in the reply just above ur last reply...

Thanks a lot for ur help..

Please tell me that is there any setColour sort of function for chaging the line or rectangle colour on click.. or i have to set a pen and recreate the line or rect over the created line...

Thanks again...

Kapil