PDA

View Full Version : QGraphicsItem reimplemented mouse events



aarelovich
23rd July 2009, 21:29
Hi:
I need I want implement a basic button because I'm building an application that only uses QGraphicsItems. I need one button so here is the code I wrote to get started:



Button::Button(int w, int h, QString cap){
caption = cap;
width = w;
height = h;
color.setRed(40);
color.setGreen(40);
color.setBlue(40);
pen.setColor(color.lighter(130));
pen.setWidth(2);
}

QRectF Button::boundingRect() const{
double margin = 2;
return QRectF(0,0,width+margin,height+margin);
}

void Button::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
Q_UNUSED(widget);
if (option->state & QStyle::State_Sunken){
qDebug() << "I'm being pressed";
painter->setRenderHints(QPainter::Antialiasing|QPainter::Te xtAntialiasing);
QBrush brush(color);
painter->setPen(pen);
painter->setBrush(brush);
painter->drawRoundedRect(QRect(0,0,width,height),20.0,20.0, Qt::RelativeSize);
}
else{
painter->setRenderHints(QPainter::Antialiasing|QPainter::Te xtAntialiasing);
QBrush brush(color);
painter->setPen(pen);
painter->setBrush(brush);
painter->drawRoundedRect(QRect(0,0,width,height),20.0,20.0, Qt::RelativeSize);
}
}

void Button::mousePressEvent(QGraphicsSceneMouseEvent *event){
if (event->button() != Qt::LeftButton){
event->ignore();
return;
}
qDebug() << "press";
QGraphicsItem::mousePressEvent(event);
update();
}

void Button::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
qDebug() << "release";
emit(clicked());
QGraphicsItem::mouseReleaseEvent(event);
}


The problem is that when I press the button all I get is the message "press" and I don't get "release" or the "I'm being pressed" message. I've compared it over and over to the elastic node's example and I can't find any differences that would make mine not work. What's even more bizarre I allready have another implemented class that also uses de the mouseRelease and mousePress events to change cursors and it works perfectly.

Any one has any idea of what I could be doing wrong?

Thanks for any help.

aarelovich
23rd July 2009, 21:33
Ok so I did a little bit more of experimenting and I found out the difference between the class I implemented that worked and this one:

If I use:
setFlags(ItemIsMovable);

Then it works. At least the messages appear correctly. Only problem is that the button obviously moves and that is something I really not want.

Any ideas? thanks.

aarelovich
23rd July 2009, 21:39
So I answered my own question:

setFlag(ItemIsSelectable)

That makes all the events work just fine.

Hope this help someone.

wysota
23rd July 2009, 23:04
This is incorrect. Button is not selectable so the logic is wrong and making an item selectable shouldn't magically cause it to receive release events.

Don't call the base class implementation in mousePressEvent() and all should work fine.

aarelovich
23rd July 2009, 23:08
Ahhh Ok.

I knew the button should not be "selectable" but it fixed my problem.
I'll do this instead

Thanks anyways, wysota.

EDIT: Worked like a charm.

wysota
24th July 2009, 00:17
EDIT: Worked like a charm.

The real question is why it works after removing the call :) Or rather why it doesn't work with the call.

aarelovich
24th July 2009, 00:22
Of course.

I know this should be the question. The thing is I've been workin my butt off with the whole QGraphicsView Framework and I've noticed that is not as "well-oiled" for lack of a better term, as the rest of Qt. Plenty of messages regarding problems with events and such are proof of it. Most of the threads with no satisfactory or 100% satisfactory answer. I was guessing that this is not as "done" as other tools.

Still, it gets beautifull results and it's pretty useful.

Now if your question is rhetorical and you actually know the answer, then by all means please tell me so I know.

Thanks.

wysota
24th July 2009, 00:42
I know this should be the question. The thing is I've been workin my butt off with the whole QGraphicsView Framework and I've noticed that is not as "well-oiled" for lack of a better term, as the rest of Qt.
I wouldn't agree. Graphics View is a much more sophisticated and tuned framework than the rest of the toolkit.


Plenty of messages regarding problems with events and such are proof of it. Most of the threads with no satisfactory or 100% satisfactory answer. I was guessing that this is not as "done" as other tools.
My guess is that people use it improperly. Of course the architecture has its problems and bugs - it's quite young and develops very dynamically. At the same time it is one of the most popular architectures in Qt so many people abuse it or reveal problems in it.



Now if your question is rhetorical and you actually know the answer, then by all means please tell me so I know.

The answer is in the source code of the mousePressEvent routine but it's almost 2AM here so, excuse me, but I'won't be looking there right now. Feel free to do that yourself and report the results here afterwards.

aarelovich
24th July 2009, 00:56
If you say it's ok then I believe you. It's just that I haven't abuse of anything. I wanted to use some of the simpler features and I've gotten several more headaches than when I tried to learn other qt tools. But anyways, there is no way I'm going to look at the mouseEvent code and understand it. But thaks for the encouragment.

wysota
24th July 2009, 10:45
Well, I did have a look. It's very educating to solve your problems by looking into Qt's source code, you should try it. Based on the code I can say that if your item doesn't have any flags set (ItemIsMovable or ItemIsSelectable (the others are ignored), to be exact), you shouldn't call the implementation of mousePressEvent from QGraphicsItem because the event will be ignored and forwarded to an item laying below or to the scene which will probably do something that causes incorrect behaviour of mouseReleaseEvent.

aarelovich
24th July 2009, 12:04
Well, that basically fits nicely with why I had to pass the events to the QGraphicsItem::mousePressEvents() in my other class, that Item effectively needed to be moveable.

I'll try what you tell me some time.

Thanks.

aarelovich
24th July 2009, 12:53
So I decided to have a look too. I've searched for the code on the web and found it here:
http://www.koders.com/cpp/fid93B09A1CC6FE667CB9FAF1986916E41EB68BA4FE.aspx?s =cdef%3Atree+mdef%3Ainsert

(To be honest I can't find it in Linux)

I think I see what you mean, but there still there is something that I don't understand.

I was calling QGraphicsItem::mousePressEvent() in my reimplementation of the mousePress and that event did work, however according to the code here if my item is neither moveable or selectable it should also be ignored, what am I missing?

aarelovich
24th July 2009, 12:56
Ok, so I've read your original answer and now i get that you've allready answered my own question.

I'm sorry.

Thanks.