PDA

View Full Version : form and its objects communication



eva2002
28th January 2010, 02:33
Hi all,

This may or may not be a qt question but I have no idea where else I could place this. I apologise if this offended some of you.

form items:
I have 1 form (call f1).
f1 contains a custom graphicsScene (with modified mouse press event) call scene for simplicity.
f1 also contain 2 labels (x, y) and a list box;

part1:
I want only to enable mouse press event (of scene) only when an item in the list box is selected.

part2:
I wanted to do is when I clicked on the scene, I want to return the x and y position of the mouse (of scene) to the 2 labels in f1.

How can I do both of these things?

vishwajeet.dusane
28th January 2010, 09:51
Hi

Go thru event filter& sending events, u can do both these things using that

wysota
28th January 2010, 10:15
I wouldn't "disable" mouse events in the scene. I would just gave a flag set in the scene according to the state of the list box. Then if the flag is set (something is selected) I would do the main thing the event is supposed to do, otherwise I would just emit a signal with mouse click position so that you can connect to it and set up the labels.

eva2002
29th January 2010, 02:15
I wouldn't "disable" mouse events in the scene. I would just gave a flag set in the scene according to the state of the list box. Then if the flag is set (something is selected) I would do the main thing the event is supposed to do, otherwise I would just emit a signal with mouse click position so that you can connect to it and set up the labels.

I would also do it that way but I have no idea how to work it out in qt. My problem is I don't know how to communication between the 2 widgets. I am still new to qt.

below are codes I did but got stuck halfway.

Mainwindow.h


....
private:
QLabel *posX;
QLabel *posY;
QListWidget *area;
mapscene *scene;


Mainwindow.cpp


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
posX = new QLabel;
posX->setMinimumWidth(50);
posX->setFrameShape(QFrame::Box);

posY = new QLabel;
posY->setMinimumWidth(50);
posY->setFrameShape(QFrame::Box);

area = new QListWidget;
area->setMaximumWidth(180);
area->setMinimumHeight(300);
//assume all items added

scene = new mapscene;
scene->setSceneRect(0, 0, 600, 600);
}


mapscene.h


class mapscene : public QGraphicsScene
{
public:
mapscene();

protected:
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);

private:
QGraphicsEllipseItem *item;
};


mapscene.cpp


const int ellsize = 5;

mapscene::mapscene()
{
item = new QGraphicsEllipseItem;
item->setBrush(Qt::red);
addItem(item);
}

void mapscene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
//check status of listbox. How to check?

removeItem(item);

item->setRect(mouseEvent->scenePos().x(),mouseEvent->scenePos().y(),ellsize, ellsize);
addItem(item);

//update posX and posY (Qlabel of Mainwindow). How to update?

QGraphicsScene::mousePressEvent(mouseEvent);
}

void mapscene::mouseReleaseEvent(QGraphicsSceneMouseEve nt *mouseEvent)
{
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}

eva2002
29th January 2010, 02:24
Hi

Go thru event filter& sending events, u can do both these things using that

I looked through the events & events filter help but no sure how to use it in my case. there is part of my implementation in my previous post. Maybe someone can guide me through there.

eva2002
29th January 2010, 04:12
Hi I manage to update the label box but I still wasn't able to get the status of the list box.

current code.



class mapscene : public QGraphicsScene
{
Q_OBJECT

public:
mapscene();

signals:
void map_plot(QPointF pt);

protected:
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);

private:
QGraphicsEllipseItem *item;
};




mapscene::mapscene()
{
item = new QGraphicsEllipseItem;
item->setBrush(Qt::red);
addItem(item);
}

void mapscene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
//check status of list box. How to do it?

removeItem(item);
item->setRect(mouseEvent->scenePos().x(),mouseEvent->scenePos().y(),ellsize, ellsize);
addItem(item);

QGraphicsScene::mousePressEvent(mouseEvent);
emit map_plot(mouseEvent->scenePos());
}

void mapscene::mouseReleaseEvent(QGraphicsSceneMouseEve nt *mouseEvent)
{
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}


My mainwindow still stays the same as the above except I added a function to update the labels and connect it to the signal emitted by the mousepressevent.

wysota
29th January 2010, 12:37
Don't check the status of the listbox in mouse events of another widget. Use signals and slots to connect to changes in the listbox's state (i.e. signals emitted by its QItemSelectionModel) to set a flag in your scene that the listbox has an item selected or not. Then just check this flag in the event. Same goes for updating the status bar - emit a signal from your scene with the new coordinates and connect it to a slot in your widget where you will update the status bar.

eva2002
29th January 2010, 23:47
I get it that I can use signals and slots to do the trick. The problem here is disp can see the mapscene (custom graphicsScene) object and therefore it can use the signals produce by that object. I have use this to update the position of the mouse.

However, since no reference of disp in mapscene, I can't see the signals emited by disp and hence wasn't able to reference to the signal from disp to notify mapscene that an item in the listbox is selected. This is the problem I am facing now.

wysota
30th January 2010, 02:06
What is "disp"? If that's an object of some kind then the answer is that you need to connect signals and slots from an object that sees both the source and target objects (which is most often the first common ancestor object of the two objects in question). If there is no such object then you can always relay (propagate) signals to the environment until a situation I described occurs.

eva2002
31st January 2010, 02:49
I manage to get it through by using pointers. Thanks for your help.