Pass mouse events from QGraphicsItem to QGraphicsScene - qt

I have a scene object derived from QGraphicsScene and custom item on it, derived from QGraphicsItem.
I want this item be "transparent" for mouse events so clicking on the item area will call
QGraphicsScene::mousePressEvent();
From the documentation:
"...To disable mouse events for an item (i.e., make it transparent for
mouse events), call setAcceptedMouseButtons(0)."
But still the scene does not receive mouce events if I click on the item area.
MyItem::MyItem(QGraphicsItem * parent) :
QGraphicsItem(parent)
{
setAcceptedMouseButtons(Qt::NoButton);
}
QRectF MyItem::boundingRect() const
{
return QRectF(0,0,100,100);
}
void MyItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
{
painter->fillRect(boundingRect(),QColor(0,0,160,10));
}
So how can I ignore mouse events for the item?
It is possible then in the future I will need to process mouse events with the item so may be right decision is to implement QGraphicsItem::mousePressEvent() and just to pass somehow the event to the scene.

You messed up evrything.
QGraphicsScene always process ALL mouse events! It is responsible for passing those events to its children (QGraphicsItems in scene). So scene receives mouse events then event is passed to respective item in scene.
So if item doesn't accept mouse event this doesn't mean the scene will process mouse event again.
It looks like that you messed up something when you did subclass a scene.
Bottom line your question is wrong.

Related

How to hide a QWidget when mouse clicked on out side that widget

I want hide a QWidget when mouse clicks out of that widget just like it have a popup flag:
auto widget = new QWidget(this);
widget->setWindowFlag(Qt::Popup); // this widget will hide, when mouse click out of that widget.
For some reason, I can't set these flags and must implement some thing myself which behaves like this.
Or can I get a mouse event out of that widget?
Solution:
As I said, I can't use Qt flags and have to implement the similar behavior myself.My solution is installEventFilter to QApplication, in the override method eventFilter,I filter the QMouseEvent and send a signal.
Yes, you can get a mouse event out of the widget.
Make a custom widget and reimplement mousePressEvent, which will catch the last click (the ouside-the-widget click that hides the "popup"). But be careful to add the call to QWidget::mousePressEvent(event) in the end, otherwise the last click will be lost and your widget will remain onscreen.
CustomWidget::CutomWidget(QWidget *parent) : QWidget(parent)
{
setWindowFlags(Qt::Popup);
}
void CustomWidget::mousePressEvent(QMouseEvent *event)
{
if (!this->underMouse()) {
//if the click is not on the widget, i.e. if it's the click that hides it,
// you caught it, do what you want to do here.
}
QWidget::mousePressEvent(event);
}
Hope it helps.

How can I distinguish wheel button click event from mouse press event?

I am wondering how i can distinguish wheel click event from mouse press event. Because i want to do different handling for these two events in pyside. Currently, every time I click the wheel button, the event is catched by mousepressevent. Can anyone explain ?
Edit: I want to implement this in a subclass of
qglwidget class
From its name, the mousePressEvent is responsible for mouse clicks while the wheelEvent is for scrolling solely. The wheelEvent will not catch the wheel button click. It is how the Qt's API is designed when it comes to mouse events processing.
In order to separate which mouse button is pressed (right, wheel or left), use button property of QMouseEvent.
This is how the code would look like using C++ (I imagine it is easy to translate it to pyside)
void GLWidget::mousePressEvent(QMouseEvent *event) // redefine the mouse event
{
switch( event->button() ) {
case Qt::LeftButton:
// do stuff for left button pressed
break;
case Qt::MiddleButton:
// do stuff for wheel button pressed
break;
// ...
}
}
So, for pyside, you only need to compare the button property of event in mousePressEvent and see whether it is Qt.LeftButton , Qt.RightButton or Qt.MidButton. Hope that helps.

How to detect a QGraphicsItem moving performing by mouse?

I have a child class of QGraphicsItem with Selectable and Movable flags. When I select many items and moving them, all recieves itemChange event. Is there any way to detect in itemChanged that mouse's button is still pressed?
Please refer to the QApplication::mouseButtons() function that will return the current state of the mouse buttons Qt::MouseButtons.
Qt::MouseButtons btns = QApplication::mouseButtons();
if (btns & Qt::LeftButton) {
// The left button is pressed.
[..]
}

Adding Custom Widget to QListWidget in QT click issue in QT?

I am adding custom widget to QListWidget.
My Custom Widget contains 2 Labels, 1 Button
/* My Custom Widget
UserDetails *myItem = new UserDetails(0," ALOA, Jeon");
UserDetails *myItem1 = new UserDetails(0," LOUIS, Stacy");
QListWidgetItem *item = new QListWidgetItem();
QListWidgetItem *item1 = new QListWidgetItem();
item->setSizeHint(QSize(0,45));
item1->setSizeHint(QSize(0,45));
ui->listWidget->addItem(item);
ui->listWidget->addItem(item1);
ui->listWidget->setItemWidget(item,myItem);
ui->listWidget->setItemWidget(item1,myItem1);
Using above Code I am adding mu Custom Widget item to QListWidget.
Now the problem is I am using One QPushButton in my CustomWidget now when i click on ListWidgetItem in ListWidget that button i want to change pressed state to some background-image and on release it should come back to normal state.For that I using stylesheet to do so but when i click on button it does not get click event of the List Widget (itemclicked SLOT of List) on double click it gets.
How to get on single click ?
This is not that simple, however it is doable. The problem is that when you click on the button the press event is not propagated to the list widget. So you have to find a way to propagate the signal back to the list widget.
When the button is pressed the pressed signal is emitted. When it is released the released signal is emitted. I will show you how to do it for one of them, you should do the same for the other.
The most straight forward way to do what you want is to add a connection between the pressed signal of the button and the slot which will modify the background of your list. What you have is a QListWidget in which there are some UserDetails widgets each of which has a QPushButton. So we have to go all the way up from the QPushButton to the QListWidget.
In your UserDetails class create a new signal, eg buttonPressed() and connect your button's pressed() signal with it. This way every time the button is clicked in your widget the widget itself will notify the world that its button has been clicked.
connect(ui->button, SIGNAL(pressed()), this, SIGNAL(buttonPressed())
Now we want to notify the QListWidget that the button has been pressed. In order to achieve this we have to connect the buttonPressed signal from the UserDetails with a slot, let's call the slot buttonPressedSlot()
connect(myItem, SIGNAL(pressed()), this, SLOT(buttonPressedSlot())
Now the slot should detect which is the sender (since all UserDetails objects will get connected to the same slot, find the corresponding QListWidgetItem and call the slot that will update the background of this item.
void LiwstWidgetClick::buttonPressedSlot()
{
QObject* signalSender = QObject::sender();
UserDetails* p = qobject_cast<UserDetails *>(signalSender);
if (p == NULL)
return;
// Get Position in list widget
for (unsigned i=0; i<ui->listWidget->count(); i++)
{
QListWidgetItem* item = ui->listWidget->item(i);
if (ui->listWidget->itemWidget(item) == p)
cellClicked(item); // THIS IS YOUR FUNCTION THAT CHANGES THE
// BACKGROUND OF THE GIVEN ITEM
}
}
You should do the same for the released() signal.
EDIT
If the button was public you could avoid the extra signal, eg if you had a function (getButton()) in your UserDetails that returned the ui->button you could have just one connection
connect(myItem->button(), SIGNAL(pressed()), this, SLOT(buttonPressedSlot()));
EDIT 2
If you just want to change the background of you button when it is pressed then you can achieve it using stylesheets. You need to entries in your stylesheet one for the normal button state and one for the pressed state. For a list of available states have a look here. Sample code follows
QListView QPushButton {
color: grey;
border-image: url(/path/to/image1) 3 10 3 10;
}
QListView QPushButton:pressed {
color: red;
border-image: url(/path/to/image2) 3 10 3 10;
}
Notice that I use the QListView Descendant Selector in order to get only these QPushButtons that are children of a QListView

How to get event of clicking out of a QGraphicsItem, being notified of focusOut

i have a class implemented from QGraphicsItem, called Node.
i have a rectangle shaped "Node" and i can do something when user clicked on it
i use mousePress and mouseRelease events.
but i want to be notified when user clicked "out of" the rectangle shape.
i tried to implement these functions:
Qt Code:
void Node::focusInEvent ( QFocusEvent * event){
cout<<"in"<<endl;
update();
QGraphicsItem::focusInEvent(event);
}
void Node::focusOutEvent ( QFocusEvent * event ){
cout<<"out"<<endl;
update();
QGraphicsItem::focusOutEvent(event);
}
void Node::hoverEnterEvent(QGraphicsSceneHoverEvent *event){
cout<<"out"<<endl;
}
these do not reacts if i click in or out of rectangle.
should i set a logic on my own for example getting the mouse position and control if it is out of rectangle?
or is there a built in method?
or how can a "Node" object know if other Node object is clicked?
also i wonder, googled but could not found that when does focusinevent and focusoutevent triggered? I guess focusOutEvent must work when i had clicked in the item, then out of the item, am i wrong?
thanks for idea.
You need to do the following when you construct your nodes:
setFlag( QGraphicsItem::ItemIsFocusable );
setAcceptHoverEvents( true );
The first line makes your item actually capable of receiving focus, and the latter makes it so your item is notified of mouse events.
Have you called setFlags method of your graphics item with QGraphicsItem::ItemIsSelectable or QGraphicsItem::ItemIsMovable ?
According to QT doc.
By default, no flags are enabled.

Resources