4
votes

My cpp application has a QMainWindow derived class, with QQuickView widget in the ui. 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.

UPDATE

After reading the comment from @user2436719, I've tried two minimal examples. It is only when using the QQuickView that this problem arises. Here is the QML app using a QML Window with the following main.qrc, which 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:
            {

            }
        }
    }

}

The second is a CPP application with a QMainWindow derived class that has a QQuickView widget in the ui. This version exhibits the problem behavior. Here is the main.qrc:

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);
}
1
I can't reproduce this behavior... I created an ApplicationWindow containing 2 TextInput as you gave for example, and if I switch to another application and come back everything works fine. I'm using qtquick 2.5, which version are you using?lolo
Thank you for checking this @user2436719! I updated my answer with some new info, based on your feedback. Looks like I only experience the problem when using a QQuickView, not a QML Window based app.Yosemite
Looks like it might be QTBUG-34414. Going to do some testing on the workaround mentioned in those comments, ask on the Qt forums if the workaround is any good, and report back.Yosemite

1 Answers

2
votes

Okay, this is QTBUG-34414. At the bottom of the comments for that bug a workaround is posted. The posted workaround fixed the problem for me, in the case of switching to other windows of my application, or to other applications. There was still no focus after closing dialogs. Putting this override in my window class fixed the problem for both cases:

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

This override worked for me with Qt 5.7 on OSX Sierra.