QPushButton bug under QT5 while pushing to go to fullscreen on macos - c++

I made a small video app with fullscreen support. While the video is playing I can push a button in my video controller and the app changes to fullscreen.
The strength thing is, when I'm in fullscreen the button has still somehow the focus in this way that when I move over it , it thinks I pushed (also the hover of the button is active even when I'm not over it with the mouse)
This behaviour end then up in a endless with to and from fullscreen when I'm not moving the mouse after pushing the button
I had here a similar problem in Qt4, but here the mouse over was only active after pushing
so perhaps somebody has an idea what's happening here, could not find anything in the Qt buglists
Georg

I don't know if it is a bug or an intended behaviour, nevertheless you may try to solve this problem in several ways. In the slot called whenever you change the size of the window, call one or several of the following QPushButton methods:
clearFocus() - that should make the button stop receiving keyboard/mouse input;
releaseKeyboard() and releaseMouse() should effectively do the same;
If you don't need the button while in fullscreen, you can also simply make it stop receiving any user input at all:
disable it (setEnabled(false));
make it invisible (invisible widgets don't receive keyboard/mouse input) by calling setVisible(false);
disconnect() the button and thus make it stop receiving any signals, and connect() it again after turning the fullscreen mode off.

Related

Qt gestures behavior when the first finger pressed is the first removed from the touch screen

I'm using Qt 5.8 on Ubuntu, running an application which handles a pinch gesture to zoom in or out an image QWidget. The problem is that sometimes, just after a pinch gesture, when interacting with other components, the image jumps. Specifically this happens when the "First Finger you put in the screen is the First one that is Removed" (FFFR from now on). One could say that this happens half of the times the pinch is performed.
I observed, by looking to the event logs, that when FFFR happens, a mouseReleaseEvent does not, but it does if the fingers are removed from the screen the other way around. So I can force a mouseButtonRelease when the pinch gesture is finishing:
if (gesture->state() == Qt::GestureFinished)
{
QMouseEvent eve( (QEvent::MouseButtonRelease), QCursor::pos(),
Qt::LeftButton,
Qt::LeftButton,
Qt::NoModifier);
qApp->sendEvent(mGraphicsView,&eve);
}
This solves my issue of the image jumping, but I still have a problem since the application still does not respond the next time I interact with it. It seems as if the application is still controlled by the pinch gesture: if I try to press a button I need to touch the screen twice, the first time just to "free" the application. I also have a mouse: if after a FFFR I move the mouse, I see another mouseReleaseEvent happen (after the first one I cause with the code above) and then I can actually press a button with my first screen touch.
This is a very strange behavior that you can easily replicate with a code example from the Qt documentation: https://doc.qt.io/qt-5/qtwidgets-gestures-imagegestures-example.html
Compile and run, selecting a folder from the dialog containing JPG or PNG images. You can experiment with the implemented gestures (pan, swipe, rotate and scale). If you perform a double click the image restets to the original view. However, if you perform a two finger gesture doing FFFR, the first time you try a double click nothing happens. In contrast, by removing the fingers from the screen the other way the image resets with the first double click, as it should. If you don't have a mouse you can double tap the screen for the same effect.
---- UPDATE ----
I think this requires an update... I have realised that the pinch gesture is not responsible for this behavior. Using the Qt code example (provided in the link above) I inserted in the class ImageWidget an event filter for QGestures. I call installEventFilter(this) in the constructor and define:
bool ImageWidget::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::Gesture)
{
gestureEvent(static_cast<QGestureEvent*>(event));
return true;
}else{
return QObject::eventFilter(obj,event);
}
}
Also, I removed the original call to the gesture handler gestureEvent. So now I'm filtering QGestures for the image widget but still handling them. Yet if I do FFFR, the application hangs!
This is a known Qt bug. It has been reported here, using the same Qt documentation example to show this effect, only including two zoom in/out buttons to illustrate the problem better. And also here, giving some explanation of the problem. Any ideas of how to go around this bug?

CMFCMenuButton not properly repainting when toggling high contrast mode

In an C++ MFC project I'm using CMFCMenuButton using MSVC 2013.
When I toggle the high contrast mode the button is not properly repainted (for comparison a normal button is displayed):
Calling Invalidate() or ShowWindow(SW_HIDE);ShowWindow(SW_SHOW); seem to have no effect - even minimizing the dialog does not cause a proper redraw. How can I force the button to repaint with the updated system color?
Update: Forcing the colors after toggling contrast mode just makes the button text visible, however the button itself, the border, is not visible.
m_ctrlOkButton.SetFaceColor(::GetSysColor(COLOR_BTNFACE));
m_ctrlOkButton.SetTextColor(::GetSysColor(COLOR_BTNTEXT));
Took me a while, but I was able to solve this. I'm inheriting from the CMFCMenuButton class so that I can handle some events:
Get the color on the button right:Handle the WM_SYSCOLORCHANGE event and call GetGlobalData()->UpdateSysColors(); (make sure it's propagated to our parent before, e.g., by __super::OnSysColorChange();)
Get the border and background right:Handle the WM_THEMECHANGED event and call CMFCVisualManager::GetInstance()->DestroyInstance(); in order to close all opened theme data handles.

Irrlicht Gui mouse will not click buttons

I'm making my first game in Irrlicht (C++), an RTS with mouse control
and when you select a tile (by clicking on it) it lights up and some gui button appear on the screen (not in a gui window mind you, I like it this way):
http://i1139.photobucket.com/albums/n549/Adam_Halley-Prinable/Untitled2.png
However, since i switched to mouse control, the buttons wont register my mouse clicks. The click goes straight through the button and selects the tile behind instead:
http://i1139.photobucket.com/albums/n549/Adam_Halley-Prinable/Untitled3.png
Is there a way I can say "Buttons get top priority for clicks"?
I'm using MyEventReceiver, which i've messed around with to accept mouse clicks and that.
Thanks a bunch :D
If anyone else has the same problem, ill tell you how I solved it :)
Go through the MyEventReceiver.h and get rid of all the "return true;"'s in the mouse section.
Don't ask me why, but it works, and appears to have no side effects. Make sure you leave the "return false;" at the end of the section there.
Your event receiver fires before the GUI gets access to the event, if you want to pass it to the GUI then you can do this by manually posting it to the GUIEnvironment in your event receiver.
if (guienv->postEventFromUser(event))
return true; // abort because the gui wanted it
// .. pick nodes
// possibly post event to scene manager
return true; // remember to return true so gui/smgr don't get the event again

How can I receive or be able to process mouseMoveEvent(s) outside my widget window?

I am writing Qt application which plays a fade-in animation whenever the mouse is moved to a certain area in the screen, and a fade out animation whenever the mouse is moved out of that same area.
I've already found a similar question here in stack overflow, however, it does not quite answer my question. (similar question here)
If I install an event filter to the application, will I be able to see ALL the events in the application even if it's outside my widget window?
If not, I am aware of an alternative involving QWidget::grabMouse() inside a reimplementation of leaveEvent(). But if I do so, will I be able to interact with anything OUTSIDE my application?
edit: though i am using the Qt library, my application is only for deployment to Windows.
I'm fairly the certain the answer is no, because events outside of your widgets are handled by the OSs window manager (and propagated onto whatever application is in that space).
However you can get the mouse position anywhere on the screen by calling QCursor::pos(), you could poll at regular intervals to find out where the mouse is.
You could try creating a completely transparent window that stays on top of the area where you want to receive mouse events, with the Qt::WindowStaysOnTopHint, Qt::FramelessWindowHint and Qt::ToolTip flags (the last one might prevent the window from receiving the focus), the Qt::WA_TranslucentBackground attribute and the mouse tracking enabled.
If you are on Windows, you can create a global hook to receive every mouse message (right before it's sent to the window under the mouse pointer). Unfortunately I don't know whether this functionality exists in other OSs.

mouse over transparency in Qt

I am trying to create an app in Qt/C++ with Qt4.5 and want the any active windows to change opacity on a mouseover event...
As i understand it, there is no explicit mouseover event in Qt.
However, I got rudimentary functioning by reimplementing QWidget's mousemoveevent() in the class that declares my mainwindow. But the mainwindow's mousemoveevent is not called whenever the mouse travels over any of the group boxes i have created in there (understandbly since QGroupbox has its own reimplementation of mousemoveevent).
So as a cheap work around, I am still using the mousemoveevent of my mainwindow but a query the global mouse position and based on the (x,y) position of the mainwindow (obtained through ->pos()) and the window size (-> size -> rHeight and rWidth), I check if the mouse is within the bounds of the area of the mainwindow and change the opacity thus.
This has had very limited success. The right border works fine, the the left changes opacity 4 pixels early. The top does not work (presumably because the mouse goes through the menubar and title bar) and the bottom changes way too early.
I thought of creating an empty container QWidget class and then place all the rest in there, but i felt that it would still not solve the big issue of the base widget not receiving the mousemoveevent if it has already been implemented in a child widget.
Please suggest any corrections/errors I have made in my method or any alternate methods to achieve this.
p.s. I doubt this matters, but I am working Qt Creator IDE, not Qt integration into VS2008 (it's the same classes anyways - different compiler though, mingw)
Installing event filters for each of your child widgets might do the trick. This will allow your main window to receive child events such as the ones from you group boxes. You can find example code here.
You may be interested in Event filters. QObject proves a way to intercept all events zipping around your application.
http://doc.trolltech.com/4.5/eventsandfilters.html#event-filters
If I understand what you are attempting to do, I would reimplement the widget's enterEvent() and leaveEvent(). The mouse enter event would trigger the fade-in and the leaveEvent would trigger the fade-out.
EDIT: After re-reading several times, I'm still not sure what you are trying to accomplish. Sorry if my suggestion doesn't help. :-)