Correct way to set focus on widget
-
I have an instance of QLineEdit, when I enter content I have a QPushButton that I can click to undo the edit and roll back, I have a slot connected to the signal emitted when the button is clicked, after roll back occurs I want the focus to return the the QLineEdit. This is the slot that is called when the undo signal is emitted:
void clsQtLineEdit::onUndoChange() { clsXMLinterface* pobjXMLIF(dynamic_cast<clsXMLinterface*>(this)); if ( pobjXMLIF == nullptr ) { return; } if ( mintUndoRedoIdx == -1 || mintUndoRedoIdx >= mpobjUndoRedo->size() ) { //Default to the end of the stack mintUndoRedoIdx = mpobjUndoRedo->size() - 1; } if ( mintUndoRedoIdx > 0 ) { const QJsonValue cobjJSON(pobjXMLIF->at(--mintUndoRedoIdx)); setData(cobjJSON.toString(), false); } pobjXMLIF->setUndoRedoButtonStates(); setFocus(); }
What seems to happen is the undo works but the next QLineEdit gets the focus not the original.
For example, my form contains two instances of QLineEdit, lets call them A and B, if A has the focus and has the content 1234, I click the button which performs the undo, but instead of A getting the focus, the focus moves to B. I then have to click A again to give it the focus.
-
Hi,
How do you connect your multiple line edits to that undo button ?
-
@SGaist , in the constructor for clsQtLineEdit:
cn = QObject::connect(mpobjWindow, &clsXMLnode::undoChanges ,this, &clsQtLineEdit::onUndoChange); Q_ASSERT_X(cn, clsQtLineEdit::metaObject()->className() ,QString("Cannot connect %1!").arg(clsXMLnode::mscszSignalUndoChanges) .toLocal8Bit().data());
I see where you are going, thank you for the suggestion, as all the instances get the same signal I need to add something to the class to track if it had the focus before the undo was pressed.
[Edit] to my event filter I added:
if ( evtType == QEvent::FocusIn ) { setControlFocus(); ...
The setControlFocus:
void clsXMLnode::setControlFocus() { if ( blnIsInteractive() == true && blnExcludedFromCC() != true ) { clsXMLnode* pobjWindow(pobjGetWindow()); if ( pobjWindow == nullptr ) { return; } QWidget* pobjWidget(pobjGetWidget()); clsXMLinterface* pobjXMLIF(dynamic_cast<clsXMLinterface*>(pobjWidget)); if ( pobjXMLIF != nullptr ) { pobjXMLIF->setUndoRedoButtonStates(); } pobjWindow->mpobjFocused = pobjWidget; } }
In the onUndoChange slot, on entry:
if ( mpobjNode->blnCheckAndRestoreFocus(*this) != true ) { return; }
This now works perfectly, thank you.
-
Just in case, Qt has the undo framework.