QQuickView: No keyboard focus after switching windows



  • My cpp application has a QML view. Inside the view are a number of QML items which accept keyboard input. When an item is clicked, I call forceActiveFocus() on the clicked item. It all works from the time I launch the application, until the time I switch to another window.

    If I switch to another application and back, or switch to another window within my application and back, calling forceActiveFocus() has no effect. The items are of a few different types, but here is a sample item:

    TextInput {
                id: textInput
                anchors.fill: parent
                inputMethodHints: Qt.ImhFormattedNumbersOnly
                onActiveFocusChanged: console.log(activeFocus)
                onEditingFinished:
                {
    
                }
    
                MouseArea {
                    anchors.fill: textInput
                    onClicked: {
                        textInput.forceActiveFocus()
                        console.log("clicked")
                    }
                }
            }
    

    When switching away I see activeFocus logged to the console as false. When I switch back again and click on the item, "clicked" is logged to the console, so the mouse event is being handled. However, onActiveFocusChanged is never called again.

    I also tried an implementation with a FocusScope as the parent of the item, got the same behavior, with focus following my click until the point I switch away to some other window and back again.



  • Okay, this is only a problem when I use a QQuickView.

    I've built two minimal examples. In a QML application Window with the following main.qrc, focus works just fine:

    import QtQuick 2.7
    import QtQuick.Window 2.2
    
    Window {
        color: "lightblue"
    
        Rectangle {
            id: textInputRect
            color: "white"
            height: 50
            width: 150
            anchors.centerIn: parent
    
            TextInput {
                id: textInput
                anchors.fill: parent
                inputMethodHints: Qt.ImhFormattedNumbersOnly
                onActiveFocusChanged: console.log(activeFocus)
                onEditingFinished:
                {
    
                }
            }
        }
    
    }
    

    In a QMainWindow derived class that has a QQuickView widget in the ui, I lose keyboard focus and can't get it back, any time I switch away from the window. Here is the (as identical as I could make it) main.qrc loaded into the QQuickView :

    import QtQuick 2.7
    import QtQuick.Window 2.2
    
    Rectangle {
        anchors.fill: parent
        color: "lightblue"
    
        Rectangle {
            id: textInputRect
            color: "white"
            height: 50
            width: 150
            anchors.centerIn: parent
    
            TextInput {
                id: textInput
                anchors.fill: parent
                inputMethodHints: Qt.ImhFormattedNumbersOnly
                onActiveFocusChanged: console.log(activeFocus)
                onEditingFinished:
                {
    
                }
            }
        }
    }
    

    From the QQuickView version, here is main:

    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    
        MainWindow window;
        QQuickView* view = new QQuickView;
    
        window.setView(view);
    
        window.show();
    
        return app.exec();
    }
    

    And here is how I set the QQuickView in the MainWindow:

    void MainWindow::setView(QQuickView *value)
    {
        view = value;
        QWidget *container = QWidget::createWindowContainer(view, this);
        view->setSource(QUrl("qrc:/main.qml"));
        ui->verticalLayout->addWidget(container);
    }


  • More information. Once I tracked it to the use of QQuickView, I found this bug report:

    https://bugreports.qt.io/browse/QTBUG-34414

    I happen to be on OS X, so I tried the workaround suggested in the comments there. It amounted to overriding event(QEvent *event) in my QMainWindow derived class. I haven't seen any negative side-effects yet (EDIT: see below), but I would really love for someone more experienced to weigh in on this solution if you've got time.

    Here is the override:

    bool MyWindow::event(QEvent *event)
    {
        if (event->type() == QEvent::ActivationChange ||
             event->type() == QEvent::WindowUnblocked) { //edited to add WindowUnblocked
            if(view->isActive()) {  //view is pointer to my QQuickView
                window()->activateWindow();
                return true;
            }
        }
        // handle events that don't match
        return QWidget::event(event);
    }
    

    EDIT:

    This works when switching to another application, or between my two main application windows, but it does not return focus (activate the window), after opening/closing a dialog. So I also call window()-activateWindow() when event->type() == QEvent::WindowUnblocked. Hopefully this is all a safe way to deal with this.


Log in to reply
 

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