PDA

View Full Version : How to get mouse click events outside the Qt window?



montylee
29th April 2009, 19:24
I have a Qt application that always stays on top. Now, i want to hide the window if the user clicks a specific area outside the Qt window. So, if user clicks outside the Qt window and outside the specific coordinates, nothing should happen and if he clicks outside the window but inside the specific coordinates the Qt window should hide. I have this code as of now:



if (event->type() == QEvent::FocusOut)
{
qDebug("focus lost");
return true;
}
else if(event->type() == QEvent::MouseButtonPress)
{
QPoint pos = dynamic_cast<QMouseEvent*>(event)->pos();
qDebug() << "mouse click position=" << mapToGlobal(pos) << "global=" << dynamic_cast<QMouseEvent*>(event)->globalPos();
return false;
}


Using the above code, i get the focus lost event when user clicks outside the Qt window but i don't get the coordinates of the click event. QEvent::MouseButtonPress case is executed only when user clicks the mouse inside the Qt window. Is there any way of getting the global mouse coordinates when user clicks outside the Qt window?

drhex
29th April 2009, 20:56
I haven't tested, but I think that's what QWidget::grabMouse() is for.

montylee
29th April 2009, 23:55
grabMouse is for grabbing the mouse. I don't want to grab the mouse, i want to get the mouse cursor position when user clicks outside the Qt window i.e. on lost focus event. Is there any way to get this in Qt or do i need to call an X11 API for the same?

wysota
30th April 2009, 00:52
Reimplement QApplication::x11EventFilter() and install an event filter on the event dispatcher as explained in the docs.

montylee
30th April 2009, 01:52
Actually i got the mouse position outside the Qt window using the following:



if (event->type() == QEvent::FocusOut)
{
qDebug("focus lost");
QPoint p=QCursor::pos();
qDebug() << "mouse position=" << p;
if ((p.x() >= 100 && p.x() <= 300) && (p.y() >= 100 && p.x() <= 700))
{
qDebug("hiding window");
hide();
}
}


So, i am able to hide my window if user clicks outside the window. The problem now is that if user clicks outside the window and outside the area i defined, i get focus lost event and the window is not hidden. Now, if user clicks inside the defined area, i don't get any focus out event since the focus was already lost earlier when user clicked outside the window.

So, the above code works only if the Qt window already has focus. Is there any way to force the focus back to the Qt window when i get focus out event? I tried grabKeyboard but it only grabs the keyboard, it doesn't make the Qt window grab focus.

Is it possible to use x11EventFilter() for forcing the Qt application not to loose focus?

wysota
30th April 2009, 10:22
This code will not work in most of the cases. If you want to test it, position the mouse cursor over your widget and press tab. Now do the same but position the mouse cusor inside your special area. After pressing tab the window will get hidden in the second case.

montylee
30th April 2009, 18:42
This code will not work in most of the cases. If you want to test it, position the mouse cursor over your widget and press tab. Now do the same but position the mouse cusor inside your special area. After pressing tab the window will get hidden in the second case.
No, the code i posted in working fine as i grab the keyboard even after the window looses focus. My main problem is that i want my Qt window never to loose focus.
Is there any way i can specify that my Qt window never looses focus (similar to Always On Top scenario). If it's not possible in Qt, can i use any X11 APIs to force focus on my Qt window?

aamer4yu
30th April 2009, 18:54
For Always on top scenario, you can have a look at Qt::WindowStaysOnTopHint (QWidget::setWindowFlags)

montylee
30th April 2009, 23:35
oh no i was just giving an example for always on top.
Mainly i want my applicatino never to loose focus but i don't know how to do it.

wysota
4th May 2009, 08:42
Make it fullscreen or the only application using the X server.

orion.zhang
18th September 2010, 08:25
try this.
first actived current widget
then
overload the event function

bool YourWidget::event ( QEvent * event )
{
if (event->type() == QEvent::ActivationChange)
{
if(QApplication::activeWindow() != this)
{
this->hide();
}
}
return QWidget::event(event);
}

szymon
13th July 2015, 22:55
maybe:

void QWidget::leaveEvent(QEvent * event)
{
close();
}