Can't get focus back in a TextField



  • I have a simple QML form that contains one TextField, some buttons, labels and a clickable link (mouse area). The TextField works fine until I open a child form (via QQuickView inside a QDialog using PyQt5) by clicking clicking on a MouseArea. After the second form is closed the TextField can no longer get the input focus.

    I used the following to check the focus in the TextField:
    @
    text: activeFocus ? "I have active focus!" : "I do not have active focus"
    @

    I have tried setting the "focus" to true from code when the child form is closed but that doesn't help.

    Is there something fundamental that I am missing? How can I return the focus to the TextField on the first form when the child form is closed?



  • I am not sure about the issue but you probably want to try calling forceActiveFocus() and not just setting the "focus" property as they mean different things.



  • Using forceActiveFocus() doesn't help either. I will make a miminal example.

    By the way, where is the detailed documentation for forceActiveFocus()?
    "The documentation for 5.1 is missing.":http://qt-project.org/doc/qt-5.1/qtquick/qquickitem.html#forceActiveFocus



  • Here is a working (or not as is the case here) example. When run from Qt Creator (qmlscene) it works as expected. When run from Python using QQuickView, the TextField in parent.qml does not get the focus back after the child window has been opened and closed.

    @
    // parent.qml
    import QtQuick 2.1
    import QtQuick.Controls 1.0

    Rectangle {

    width: 640
    height: 480
    
    signal closed
    
    Button {
        text: qsTr("Open child window")
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        onClicked: {
            child.visible = true
        }
    }
    
    TextField {
        id: text_field1
        x: 93
        y: 299
        width: 471
        height: 22
        placeholderText: "Text Field"
        text: activeFocus ? "I have active focus!" : "I do not have active focus"
    }
    
    Child {
        id: child
        visible: false
        modality: Qt.WindowModal
    }
    
    Button {
        id: button1
        x: 488
        y: 397
        text: "Close"
        onClicked: {
            closed()
        }
    }
    

    }
    @

    @
    // Child.qml
    import QtQuick 2.1
    import QtQuick.Controls 1.0
    import QtQuick.Window 2.0

    Window {
    width: 500
    height: 300

    TextField {
        id: text_field1
        x: 73
        y: 189
        width: 227
        height: 22
        placeholderText: "Text Field"
    }
    
    Button {
        id: button1
        x: 373
        y: 187
        text: "OK"
        onClicked: {
            close()
        }
    }
    

    }
    @

    @
    // example.py
    import sys
    from PyQt5 import QtWidgets, QtCore, QtQuick
    from PyQt5.QtWidgets import QDialog, QWidget

    def qt5_qml_dir():
    import os
    import subprocess
    qmldir = subprocess.check_output(["qmake", "-query",
    "QT_INSTALL_QML"]).strip()
    if len(qmldir) == 0:
    raise RuntimeError('Cannot find QT_INSTALL_QML directory, "qmake -query '
    + 'QT_INSTALL_QML" returned nothing')
    if not os.path.exists(qmldir):
    raise RuntimeError("Directory QT_INSTALL_QML: %s doesn't exist" % qmldir)

    # On Windows 'qmake -query' uses / as the path separator
    # so change it to \\. 
    if sys.platform.startswith('win'):
        import string
        qmldir = string.replace(qmldir, '/', '\\')
    
    return qmldir
    

    class FocusTest(QDialog):

    def __init__(self, parent=None):
        super(FocusTest, self).__init__(parent)
        self._parent = parent
    
        view = QtQuick.QQuickView()
        self._view = view
        view.setResizeMode(QtQuick.QQuickView.SizeViewToRootObject)
        
        # add the Qt Quick library path
        view.engine().addImportPath(qt5_qml_dir())
    
        view.setSource(QtCore.QUrl('parent.qml'))
        w = QWidget.createWindowContainer(view, self)
        w.setMinimumSize(view.size())
        w.setMaximumSize(view.size())
        r = view.rootObject()
        self._root = r
        
        r.closed.connect(self.onClosed)
    
    def onClosed(self):
        self._view.close()
        self.accept()
    

    if name=="main":
    app = QtWidgets.QApplication(sys.argv)
    s = "Test placeholder"
    label = QtWidgets.QLabel(s, None)
    label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
    label.setWindowTitle(s)
    label.resize(800, 400)
    label.show()

    s = FocusTest(label)
    s.accepted.connect(label.close)
    s.open()
    app.exec_()
    

    @



  • I have "reported this as a bug.":https://bugreports.qt-project.org/browse/QTBUG-34414



  • Can't you just do it like this:

    @
    Child {
    id: child
    visible: false
    modality: Qt.WindowModal
    onVisibleChanged: {
    if(visible === false){
    text_field1.forceActiveFocus();
    }
    }
    }
    @

    That should set the focus back to the textfield if the Child is closed (and not visible any more). This is more or less what Jens was suggesting I think.



  • Thanks, I tried doing that from code but it didn't work. The above doesn't work either.



  • I have temporarily worked around this problem by hiding the parent form when the child form is shown and then showing it again when the child form is closed.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.