I'm having a table with 100 datas. I need to receive mouse press event while clicking on the table.
Here is the code:
ui->tableWidget->viewport()->installEventFilter(this);
bool Dbtable::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::MouseButtonPress)
{
debugLog("# TABLE WIDGET IS PRESSED");
return ;
}
}
Now the table is not visible.
Could any one help me in solving this?
have you tried returning QWidget::eventFilter()
Related
Brief description of my application and my question:
In a QTabWidget I have several groupBoxes containing each 2 QRadioButtons.
E.g.
Select Menu (groupBox): (RadioButton:) A (RadioButton:) B
At one point of time, only one Menu can be active.
Both radioButtons are connected to each othe ->
When I click radioButton A and set it true, radioButton B is automatically set false - and the other way round.
When trying to change the menu setting, before a click signal is emitted, I would like to issue a QMessageBox Warning "Are you sure you want to change the menu? This can cause severe damage to your device." -Yes/No.
When clicking Yes, I would like to change the menue setting. When clicking No, I would like everything to remain as before.
The only problem I have is: When issuing the QMessageBox in the on_radio_button_toggled slot, the radioButton state has already changed to true.
Even if I change the state in the slot again and correct them, it looks like the state has already changed when the pop up message shows up. I don't want that because that implies that the state of the menue has already changed.
Where or How can I let a QMessageBox pop up before emitting the actual signal slot - when clicking the radio Button?
Thank you very much for your help.
Update:
I have now implemented an eventFilter as recommended. Here is my source code:
ui->radioButtonMenu1->installEventFilter(this);
ui->radioButtonMenu2->installEventFilter(this);
SubmenuOne is a QWidget. It is integrated into the MainWindow by a QTabWidget (via placeholder).
bool SubmenuOne::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::MouseButtonPress)
{
QMessageBox::StandardButton reply;
reply= QMessageBox::question(this,tr("WARNING"),tr("Changing the settings may cause severe damage to your device! Please confirm your decision."),QMessageBox::Yes|QMessageBox::No);
if (reply == QMessageBox::Yes)
{
//QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
//keyEvent->accept();
//event->accept();
qDebug("Yes.");
return false;
}
else
{
qDebug("No.");
return true;
}
}
}
You have to use bool eventFilter(QObject *obj, QEvent *event); Declare event filter in your window, then instal event filter to every radiobutton like this: radioButton1->installEventFilter(this);. Then at eventFilter check event type: if (event->type() == QEvent::MouseButtonPress) and show your QMessageBox. Then you can accept event and return true or false depending on user choise.
bool SubmenuOne::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::MouseButtonPress)
{
QMessageBox::StandardButton reply;
reply= QMessageBox::question(this,tr("WARNING"),tr("Changing the settings may cause severe damage to your device! Please confirm your decision."),QMessageBox::Yes|QMessageBox::No);
if (reply == QMessageBox::Yes)
{
static_cast<QRadioButton*>(obj)->setChecked(True);
}
event->accepted();
return true;
}
return QMainWindow::eventFilter(obj, event); //you forget this. QMainWindow is just base class of your SubmenuOne.
}
I implemented a Graphicsview in which I load an Image and the user can add different Item such as rectangle or line. The user has also the possibility to move these objects in the scene. Up to here everything is ok.
Now I tried to implement some mouse events in this way:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->graphicsView && enable_mouse_event==true)
{
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
point_mouse = ui->graphicsView->mapFrom(ui->graphicsView, mouseEvent->pos());
return true;
}
if (event->type() == QEvent::MouseMove)
{
int scroll_x, scroll_y;
scroll_x = ui->graphicsView->horizontalScrollBar()->value();
scroll_y = ui->graphicsView->verticalScrollBar()->value();
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
point_mouse_move = ui->graphicsView->mapFrom(ui->graphicsView, mouseEvent->pos());
QRect rect(point_mouse_move.x()+scroll_x-50, point_mouse_move.y()+scroll_y-50, 100, 100);
zoom_image = image_clone.copy(rect);
ui->zoom_label->setPixmap(QPixmap::fromImage(zoom_image));
return true;
}
}
return false
}
with in MainWindow.cpp
ui->graphicsView->installEventFilter(this);
In this way the press event is recognized while the move event is recognized only on the border of the Qgraphicview object (the property mouseTracking is set to true) and I'm still able to move the other object.
To solve the problem of the move event I tried to modify the code by adding:
->viewport()
to the graphicview object.
In this way both the mouse events (press and move) work correctly but I'm no longer able to move the other objects (rect and line)
Any Idea how can I recognize all the mouse events and at the same time move the other objects??
thanks
The problem was that I was filtering out the events and they never go to the window. Instead of setting the returns true just set the return false!
Thanks to #thuga
I've Dialog that shows folders (in treeView) and files (in listView) respectively. In listView doubleClick signal is handled by a slot that Qt created while I used Designer with aproppriate slot to be implemented. The problem is that I'm not able to handle RIGHT MOUSE click. Is there a solution?
P.S.
I've googled for a while to solve this problem, it seems that inheriting QListView and overriding solve the problem. But in my case I've already populated Qt's standart QListView using Designer.
In this case you can use event filter:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->listView->viewport() && event->type() == QEvent::MouseButtonDblClick)
{
QMouseEvent *ev = static_cast<QMouseEvent *>(event);
if (ev->buttons() & Qt::RightButton)
{
qDebug()<< "double clicked" << ev->pos();
qDebug()<< ui->listView->indexAt(ev->pos()).data();
}
}
return QObject::eventFilter(obj, event);
}
To use eventFilter you should also:
protected:
bool eventFilter(QObject *obj, QEvent *event);//in header
and
qApp->installEventFilter(this);//in constructor
Possible addition to your problem. If you want do different things when user clicks left or right mouse buttons you should handle lest and right clicks in filter, without doubleClick signal (because it emits signal in both cases) and your code can be something like:
QMouseEvent *ev = static_cast<QMouseEvent *>(event);
if (ev->buttons() & Qt::RightButton)
{
qDebug()<< "RightButton double clicked";
//do something
}
if (ev->buttons() & Qt::LeftButton)
{
qDebug()<< "LeftButton double clicked";
//do something
}
In my case, I started trying to catch mouse events when a user right-clicked on a line in the QListView, but they never came through. However, all I really wanted to do was popup a context menu, and it turns out the contextMenuEvent did get through! So I didn't have to subclass QListView, just added a contextMenuEvent() to my widget that contained the QListView.
This was Qt3, so your mileage will most definitely differ.
Quick question, why does:
void roiwindow::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsScene::mouseMoveEvent(event);
qDebug() << event->button();
}
return 0 instead of 1 when I'm holding down the left mouse button while moving the cursor around in a graphicscene. Is there anyway to get this to return 1 so I can tell when a user is dragging the mouse across the graphicscene. Thanks.
Though Spyke's answer is correct, you can just use buttons() (docs). button() returns the mouse button that caused the event, which is why it returns Qt::NoButton; but buttons() returns the buttons held down when the event was fired, which is what you're after.
You can know if the left button was pressed by looking at the buttons property:
if ( e->buttons() & Qt::LeftButton )
{
// left button is held down while moving
}
Hope that helped!
The returned value is always Qt::NoButton for mouse move events. You can use Event filter to solve this.
Try this
bool MainWindow::eventFilter(QObject *object, QEvent *e)
{
if (e->type() == QEvent::MouseButtonPress && QApplication::mouseButtons()==Qt::LeftButton)
{
leftbuttonpressedflag=true;
}
if (e->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);
if(leftbuttonpressedflag && mouseEvent->pos()==Inside_Graphics_Scene)
qDebug("MouseDrag On GraphicsScene");
}
return false;
}
And also don't forget to install this event filter in mainwindow.
qApplicationobject->installEventFilter(this);
As the title suggests, is there a way for a disabled widget to receive mouse events?
I'm using QWidget::setEnabled() for changing the appearance of widgets but I still want to receive their mouse events. Thanks in advance :)
You can do this with an event filter on the widget in question. See QObject::eventFilter(). Your implementation might look something like this:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (ui->pushButton)
{
if (event->type() == QEvent::MouseButtonRelease)
{
qDebug() << "mouse button";
return true;
} else
{
return false;
}
} else
{
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
}
}
This will work even if the button is disabled.