Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QQuickView: No keyboard focus after switching windows
Forum Updated to NodeBB v4.3 + New Features

QQuickView: No keyboard focus after switching windows

Scheduled Pinned Locked Moved QML and Qt Quick
3 Posts 1 Posters 2.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • YosemiteY Offline
    YosemiteY Offline
    Yosemite
    wrote on last edited by Yosemite
    #1

    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.

    1 Reply Last reply
    0
    • YosemiteY Offline
      YosemiteY Offline
      Yosemite
      wrote on last edited by
      #2

      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);
      }
      
      1 Reply Last reply
      1
      • YosemiteY Offline
        YosemiteY Offline
        Yosemite
        wrote on last edited by Yosemite
        #3

        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.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved