issue focusing QLineEdit rendered to QGraphicsScene - qt

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.

Related

Showing a QMessageBox breaks QLineEdit highlighting

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);

Qt: display qgraphicsitem in a widget

I got a QGraphicsScene that contains QGraphicsItems. On clicking such an item I open a dialog. I now want the item to be displayed in an area of the dialog.
I tried a QGraphicsView (in the dialog) and "pointed" it to the item which works allmost perfectly. The problem is, that it is possible to click the item in the dialog which would open a new dialog.
So my question: is there a easy way to tell QGraphicsView to ignore any input events? If not, is there a easy way to display a QGraphicsItem within a widget?
I am feeling so stupid...
QGraphicsView::setInteractive(false) did the trick.
I am still able to move the icon with the mouse wheel but this can probably be avoided by restricting the scene rect with setSceneRect()
You can install an event filter, on the QGraphicsView, which ignores input events. The Qt documentation states:
In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.

in Qt how to know which component (placed on a widget or form ) is currently focused?

I am doing work on Qt. i am not using android. It's just a desktop application running on windows/linux.how to know which component (placed on a widget or form ) is currently focused ?
i have onscreen keyboard which appears when a QLineEdit,QTextEdit or QPlainTextEdit get focused and hide when these lost focus.But when i switch focuse from one TextEdit(or lineEdit,PlainTextEdit) to Another TextEdit(or lineEdit,PlainTextEdit) my keyboard hide and again show.I just want to stop this
If you want to stop the keyboard from flickering when the widget it's coming from and the one it's going to are similar then you could perhaps implement a timer. I imagine you have the lost focus signals going to your code that is hiding the keyboard. Instead of really hiding it, you can start a timer like
QTimer::singleShot(500, this, SLOT(really_close_keyb()));
Within that really_close_keyb() slot you could implement code to check if the widget that currently has focus should have a keyboard or not, and if it should then you don't hide it.
With this your keyboard will be up for 1/2 sec after the user focuses out of a line edit, giving enough time to focus on another one without losing the keyboard. Adjust the timing to suit.

How to remove focus from a QLineEdit when anyplace else on the window is clicked

I'm working on a custom Qt button that allows you to edit the text on the button if you double click it. When the button is double clicked, a QLineEdit appears where the text on the button is allowing the user to edit the text on the button. My requirement is that if the user clicks anywhere in the application window, the QLineEdit should disappear and cancel the edit operation. This works in some cases. Specifically, it works if I click on anything that is capable of text entry. Other portions of the window don't work as expected. I'll click on a blank portion of the application window, and the QLineEdit retains its focus. How can I remove its focus in these cases?
I've found a solution that seems to work, though I'm still open to other options if there are any. I'm using PyQt4, so my example is in python:
Create a subclass of QLineEdit just so I have a new type. I don't want or need this behavior on all QLineEdit instances; just these specific ones.
class MyLineEdit(QtGui.QLineEdit):
pass
Now, in my QMainWindow subclass, I override the mousePressEvent() implementation. It gets the currently focused widget. If that widget is of type MyLineEdit, clear the focus.
class MyMainWindow(QtGui.QMainWindow):
def ...
def mousePressEvent(self, event):
focused_widget = QtGui.QApplication.focusWidget()
if isinstance(focused_widget, MyLineEdit):
focused_widget.clearFocus()
QtGui.QMainWindow.mousePressEvent(self, event)
def ...
This gets me the behavior I'm looking for so that if the user clicks anywhere on the application's window, the focus is cleared.
Edit: I did find one caveat to this. I have a QTreeView in the main window. If the user clicks on the tree view, focus is not removed from the text edit field.
Catch the clicked() signal of your parent widget and call yourLabel->clearFocus() (that unfortunatelly happens to not be a slot, making things more complicated) there.
I followed Grant Limberg instruction here but figured out that, in my case, a simple:
QApplication.focusWidget().clearFocus()
would fix the problem.
I'm not sure if this also works in Qt4 (I'm using PyQt5) but you can change the FocusPolicy of the QMainWindow or parent widget to clear the focus in the QLineEdit. As per https://doc.qt.io/qt-5/qwidget.html#focusPolicy-prop
I've changed the policy of my QMainWindow to Qt.StrongFocus and it worked like the functionality described in the question.
If done in C++ I would do something along the lines of:
connect(myWidgets->MyLineEdit, SIGNAL(returnPressed()), this, SLOT(onLineEditDone());
void onLineEditDone()
{
myWidgets->MyLineEdit->clearFocus();
}
For this particular case I would use editingFinished() instead of returnPressed(), probably, but I would NOT use textChanged(QString).

Virtual keyboard for QtWebKit based browser or how can I get the currently focused text field?

I'm working on implementing a virtual keyboard for a QtWebKit based browser. I'm having a lot of difficulty understanding how QtWebKit paints the controls within the actual page. Initially I thought they were QLineEdit instances, but they are not. Diving into implementation it appears that the glue code between Qt and WebKit paints the text field using QStyle and QPainter. Unfortunately, I'm very new to Qt and so I dont understand where in the event loop the mouse presses for these events are interpreted. I found Editor::canEdit() deep in the call stack, and now I can bring up the virtual keyboard when the user clicks on a text field within the page. The virtual keyboard then expected a pointer to a QWidget instance, but Edito::canEdit() doesn't carry that information and I can't find anywhere where a QWidget like instance is exposed. I'm really stumped, any advice would be most welcome.
Thanks!
You might get better luck by hooking the virtual keyboard into the Qt input method system. Search for "InputMethod" in the source code of QtWebKit Api, i.e. the qweb*.* files.

Resources