Showing a QMessageBox breaks QLineEdit highlighting - qt

I have a C++ Qt 4 application written for Raspberry Pi. I'm experiencing an odd side-effect of showing a QMessageBox and I don't know enough about Qt to debug it.
The pi has a touchscreen, so I launch the application with unclutter to hide the mouse cursor. (Though this doesn't affect my issue... I have tried without unclutter just in case.)
I have sub-classed QLineEdit to override focusInEvent() and focusOutEvent() to select-all when a LineEdit gets focus, and deselect-all when it loses focus.
Before showing any QMessageBoxes, everything works perfectly - tapping on a QLineEdit selects all the text; tapping the next one de-selects the previous QLineEdit, and selects the new QLineEdit.
After showing a QMessageBox, my overridden events stop working, and QLineEdits no longer auto-select and de-select.
If I add:
msgBox.setWindowFlags(msgBox.windowFlags() | Qt::Popup);
before I exec() the QMessageBox, then text highlighting continues working normally, but the cursor is displayed and flickers while the QMessageBox is on the screen.
It seems like there is a side-effect of showing the QMessageBox that affects the calling window and my sub-classed QLineEdit boxes... but not if the QMessageBox has the Popup flag set!
I've tried storing and manually re-loading the flags on the main window, and that does nothing, so it doesn't appear to be flags on the main window.
One more oddity: everything works fine if I run the application remotely over XMing and SSH... it's only when it's run locally on the Pi in plain-old X11 that it freaks out.
Any thoughts on how to debug this? Thank you!

I was able to work around this by doing two things.
First, I updated the flags of the QMessageBox before opening it:
msgBox.setWindowFlags(Qt::Popup);
msgBox.exec();
and second, I hid the cursor in Qt code, rather than relying on Unclutter; this fixed the flickering cursor issue:
QApplication::setOverrideCursor(Qt::BlankCursor);

Related

QToolButton Remain Pressed after finger has been removed from Touchscreen

I have a small Qt Desktop application (in C++) which I need to make it work in a touch screen device running Window 10. The device has a touchscreen and application works perfectly with keyboard and mouse.
I am not expert in developing Qt Application and that's why unable to resolve this could be silly isssue.
However, when I try to use touchscreen, the last touched QToolbutton remain pressed even if I have moved my finger away from the touchscreen and when I touch somewhere else, then that QToolButton is released.
I expect the Qtoolbutton to behave just like when it is pressed using a mouse. Once I move my finger off the touchscreen, it should be released.
I tried to resolve this issue with the following:
btn->setAttribute(Qt::WA_AcceptTouchEvents);
And
qApplication.setAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
But it didn't help. I think I am missing a very small issue and after that Qt will handle all the touch related events on it's own and will show the right behavior.
I am cross-compiling on my Ubuntu machine using MXE. Qt version is 5.12.
I think I am missing a very small issue and after that Qt will handle all the touch related events on it's own and will show the right behavior.
QWidget subclasses, including QToolButton, do not handle touch events on its own. It is not even needed that Qt emulate mouse events. You are seeing the effects in your application of emulated mouse events synthesized by Windows. This makes possible for ancient Windows programs designed to be used with mouse will work somewhat in modern touch enabled Windows tablets. But the mouse emulation is hardly perfect.
If the behavior is unacceptable for the QToolButton class, you have the option of subclass it and handle touchevents as you see fit, overriding mouse events as well, to avoid the synthesized events to be handled as well.
I had the same problem. I solved it by changing the signal to which the slot is connected.Previously I was connected my slot to QPushButton::pressed. To fix it, change the connect to use the signal QPushButton::clicked:
connect(my_button, &QPushButton::clicked, this, &MyClass::onMyButtonClicked);

How to hide mouse cursor in Qt Application?

qApp->setOverrideCursor() method works successfully, if I want to hide mouse cursor, except one condition. If I add a dialog that is modal, and while it is shown, if the cursor is out of dialog's borders, it is shown again. Have you got any idea about the problem?
It does not matter how the solution for hiding mouse cursor is; whether by Qt or at the operating system level. My operating system is Windows 7.
You cannot hide the mouse cursor when it leaves your window (or dialog-window), because it is then handled by the window-manager of your OS. A workaround would be to constrain the mouse to your window/dialog, so it cannot leave. You will either need to look through the MSDN to find the specific windows functions to do it, or do it like in kshegunov's code example on the Qt-forums: https://forum.qt.io/topic/61832/restrict-mouse-cursor-movement/12

hide system cursor in system wide

I want to hide system cursor for 10s for some reason ,but I found
cursor.setShape(Qt.BlankCursor)
can only hide mouse cursor that is associated with QWidgets ,not in system wide ,i.e. when mouse cursor is hovering on QWidgets, it is invisible ,otherwise it is visible ,so is there any way to hide system cursor in system wide?
The win32 system call ShowCursor works per-window only. You can access this from either ctypes or pywin32's win32api. But apparently the cursor drawing is controlled by display driver and can only be affected by specific windows. You can't force another window to hide its cursor. Two options:
use ShowCursor(False) on your window, and for the display background, create a root window application that you spawn from your GUI app, it hides cursor; your app would cause it to exit after 10 seconds, but again if user moves mouse over other app windows they will see cursor.
make your application a root window application; then while in view, ShowCursor(False) will make cursor disappear everywhere on screen except system toolbar (which is a good thing).
I don't think it is a good idea anyways; what if your app crashes while the mouse is hidden? Then user can't use their desktop easily. Definitely good reason that this is not allowed.
Best approach is to think of a different solution to whatever problem led you to try cursor hiding.

Detecting click outside QWidget

My application has non-rectangular popup widgets.
their class defines the following to achieve that transparency:
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
I also use:
this->setWindowFlags(Qt::Popup| Qt::FramelessWindowHint);
The problem is that on windows 7, an automatic "shadow" is being drawn on the bottom and right sides of my window. This is highly undesirable.
So, I tried using Qt::Tool instead of Qt::Popup
this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
This works visually. No shadow, but now a mouse click outside my widget window will not automatically close/hide it as it would have done with a Qt::Popup.
So, I need one of these two solutions:
A way to have Qt::Popup and get rid of that automatic windows shadow decoration
A way to let the Qt::Tool window a mouse click occurred outside of it.
One note: My application is built for Windows XP and up. I cannot use a Vista/Win7 only runtime DLLs, nor can i have a "Windows XP" and "Vista and up" separate builds.
Any advice will be welcome.
You could manually watch for when the focus changes from your Qt::Tool window. So basically you watch for when the focus goes onto another window of your process or when your application loses focus.
How to detect that my application lost focus in Qt?
Hope that helps.
Finally after realizing that no amount of "SetFocusPolicy" calls will allow me to receive those events for a Qt::Tool window, I've resorted to something else to fix my problem:
I kept the Qt:tool as Qt::Popup caused an undesired shadowing effect, tarnishing my owner draw frame. Removing this style cannot be done in Qt and I didn't want to mess with platform specific conditional code.
I installed an event filter with my Qt::tool window and I began receiving events that assisted me in understanding when other parts of my application were clicked, or if the application itself lost focus to another application. This was what I needed, functionality wise. I could also get an event when users click the non-client areas of the application's main window, such as the windows caption so that I can close it when dragging begins etc.
My solution for Windows 7:
QDialog *d = new QDialog;
d->setStyleSheet("background:transparent;");
d->setAttribute(Qt::WA_DeleteOnClose, true);
d->setAttribute(Qt::WA_TranslucentBackground, true);
#ifdef Q_OS_WIN
d->createWinId();
#endif
d->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
d->show();
I set my QListView
d->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
Install eventfilter and used MousePressEvent to hide qlistview widget.
MousePressEvent on list never comes to filter they produce other events which I didn't debug.
So if you want to design auto completer this will be perfect. Tested in Qt5.3.1.

issue focusing QLineEdit rendered to QGraphicsScene

I render Qt gui elements on my own 3d application screen by rendering Qt stuff to QImage and then drawing that on the screen. I redirect input to QGraphicsScene, but not everything works. Clicking buttons works fine while clicking QLineEdit or web page elements in QWebView doesnt. However doubleclick seems to work - doubleclicked QLineEdit would select some text, but still would not gain focus. What could be causing this?
I had the exact same problem. It seemed i had
QGraphicsView.keyPressEvent(self, keyEvent)
implemented in my graphicsView. Had to resend the event up the chain of inheritance.
I also implemented keyboard event sending. No matter how i send events (QGraphicsScene::keyPressEvent()/QGraphicsScene::keyReleaseEvent() or QApplication::sendEvent) text is not typed into control, even if some text is selected in QLineEdit (text should be overwritten, shouldnt it?). I suspect this is because of QLineEdit not gaining focus by clicking it, but i cant find out why it is not focused. All events are sent to my subclass of QGraphicsScene.

Resources