I have a QWidget with a QGraphicsView and a push button. The QGraphicsView has to take mouse press and release events to detect a swipe .At the same time push button should run a small function on clicked. I used an event filter in the QWidget to detect the mouse events.
bool Widget::eventFilter(QObject * obj, QEvent * event)
{
// Capturing keyboard events for moving
if( event->type() == QEvent::KeyPress )
{
//Do something
}
//Capturing mouse events for swipe
else if( event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*> (event);
swipe_startPoint = mouseEvent->pos();
}
else if( event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*> (event);
swipe_endPoint = mouseEvent->pos();
swipeDirection();
}
else
{
QWidget::eventFilter(obj,event);
}
}
In the constructor of the Widget class i have the following
ui->graphicsView->installEventFilter(this);
The problem is that the button is getting clicked but the MouseButtonRelease event that sets the 'swipe_endPoint' value is not working.
When i set
ui->graphicsView->grabMouse();
the mouse pressed and released events are working perfectly but the button stops accepting the events.
Other things that i have tried are :-
Set the event filter to the viewPort
ui->graphicView->viewPort()->installEventFilter(this);
Please help me get this mouse event working. Thanks in advance.
Note : Using QT 5.6.0 in Ubuntu
Related
i made a special videoplayer based of hikvision sdk with qtcreator in cpp
i have an void :
void QtVsPlayer::FullScr()
{
if (QtVsPlayer::isFullScreen()) {
QtVsPlayer::showNormal();
this->ui->menubar->setVisible(true);
if (!Zoomed)
this->ui->statusbar->setVisible(true);
} else {
QtVsPlayer::showFullScreen();
this->ui->menubar->setVisible(false);
this->ui->statusbar->setVisible(false);
}
return;
}
this void work, i have fullscreen video.
now in mousemove event i have
if (!this->ui->actionMasquer_les_controles->isChecked() and
WVideoCtrls->isHidden() and
this->ui->actionAuto_hide_controls->isChecked()) {
if(!Zoomed and QtVsPlayer::isFullScreen() == false)
ui->statusbar->setVisible(true);
WVideoCtrls->show();
WVideoCtrls->activateWindow();
WVideoCtrls->raise();
this->centralWidget()->lower();
this->centralWidget()->stackUnder(WVideoCtrls);
}
if (QtVsPlayer::cursor() == Qt::BlankCursor) {
QtVsPlayer::unsetCursor();
}
return;
the goal is to display videocontrols, like play, pause and so on, but not the status bar in full screen, but it is shown, zoomed is false but isfullscreen is no such value
i tried ui->centralwidget, this->isfullscreen, is->fulsreen, & , &&, and, but statusbar is displayed in fullscreen when mouse move and hide after my timer hider
I have implemented the panning view on the QGraphicsView, using the mouse move event using
void View::mouseMoveEvent(QMouseEvent* event) {
pan();
QGraphicsView::mouseMoveEvent(event);
}
and in the scene of this view I have added few items where some of the items are resizable, so I implemented
void Item::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(m_resizeMode)
{
resize();
e->accept();
}
}
I tried to filter the mouse move not to propagate to any further using e->accept()
but my View mouseMove event has been called first , so when ever I tried to resize the item, the view started to pan all the way.
How can I avoid this event propagation from view to scene.
You can call the base class implementation of the QGraphicsView and check if the event is accepted. However I would do this in the mousePressEvent instead of the mouseMoveEvent. After all this is where you determine if you should resize an item or do some panning. This is how I do something similar in my project:
void View::mousePressEvent(QMouseEvent *event)
{
...
QGraphicsView::mousePressEvent(event);
if(event->isAccepted())
move = false;
else
move = true;
}
void View::mouseMoveEvent(QMouseEvent *event)
{
if(!move)
{
QGraphicsView::mouseMoveEvent(event);
return;
}
... // you would do the panning here
QGraphicsView::mouseMoveEvent(event);
}
void View::mouseReleaseEvent(QMouseEvent *event)
{
if(!move)
{
QGraphicsView::mouseReleaseEvent(event);
return;
}
else
{
...
move = false;
}
QGraphicsView::mouseReleaseEvent(event);
}
The view will always receive the mouse event first.
So, in the view, check to see if the mouse is over an item before allowing it to pan by getting the mouse pos in scene coordinates and retrieving the items at that position with QGraphicsScene::items( )
I am using QMouseEvent and QKeyEvents in my program. I programmatically make various widgets (QDockWidgets and QCustomPlots).
I would like to use a single click and keypress handler function. However, I am struggling to get the widget that is actually being clicked, so that I can do certain stuff within that widget.
Is there a way to return from a ClickEvent the name of the widget that was clicked?
You can implement eventFilter in your mainWindow and listen for events from widgets there :
bool MainWindow::eventFilter(QObject * obj, QEvent * event)
{
if((myWidget *)obj == widget1 && event->type()==QEvent::KeyPress)
{
int pressedKey = ((QKeyEvent*)event)->key();
...
}
else if((myWidget *)obj == widget2 && event->type()==QEvent::MouseButtonRelease)
{
if(((QMouseEvent*)event)->button() == Qt::LeftButton)
{
...
}
}
return false;
}
Also do not forget to install event filters for your widgets in the mainWindow constructor :
widget1->installEventFilter(this);
widget2->installEventFilter(this);
Focus events don't work because they're not sent if you activate your window by clicking on its non-client frame. Also, if you click the internal components of the window THEY will get the focus event, not your window, but the window will still be activated, even if it wasn't active or focused before.
The event you want is QEvent::WindowActivate. Override event() to process it:
bool YourWidget::event(QEvent *e)
{
if (e->type() == QEvent::WindowActivate) {
// window was activated
}
return QWidget::event(e);
}
Qt provides several virtual event handling functions you can use. Since the activation of a window changes its state, you want to handle some change events:
void MyWidget::changeEvent(QEvent * e) {
if(e->type() == QEvent::ActivationChange && this->isActiveWindow()) {
// .. this is now the active window
}
}
References
changeEvent
isActiveWindow
I have a class inherits QWizard, and add 2 independent QWizardPage(s). Before go to the next page, I want to do some job (i.e. check internet connection) on the first page. User may click 'next' button by mouse, or directly press enter/return by keyboard since the 'next' button is focused by default. So I install a eventfilter for the button:
button(QWizard::NextButton)->installEventFilter(this);
Then in the wizard class implement the event handling code:
bool MyWizard::eventFilter(QObject *watched, QEvent *event)
{
if (watched == button(QWizard::NextButton))
{
if (currentId() == startPageId)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter)
{
// Do something. Cannot be reached.
}
}
else if (event->type() == QEvent::MouseButtonPress)
{
// Do something. Can be reached.
}
}
}
return QWizard::eventFilter(watched, event);
}
As I tried many times, clicking mouse can always make my event processing code run, but pressing key makes nothing to do. Another curious thing is, press mouse on button without releasing, then move away and release, the wizard stays on first page, now I can press key and all that is OK.
Could any one help to find the reason, is that a Qt bug? how can I make the key event work properly?
Try another simple solution without installing event filter.Use QkeyPressEvent in your main App.
void YourAppClass::keyPressEvent(QKeyEvent *e)
{
if(Nextbutton->hasFocus() && e->key()== Qt::Key_Return || e->key() == Qt::Key_Enter)
{
Do your job//I guarantee this will be reached upon pressing return with button focus
}
}
You can add mouse-click functionality in nextbutton's clickevent().