Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[Windows] Retrieving a window handle of a control using objectName



  • Hello,

    I am working on an application featuring a video stream, played by a .dll plugin and shown in a QML-based GUI, with various controls on top (overlaying the stream). In order to play the stream, I have to retrieve a handle of the QML object and pass it to the DLL. From what I've read, the way to do that is via the objectName property, in conjunction with the findChild() method. I have the following:

    //MainWindow.qml:

    ApplicationWindow {
    /* ... */
      Rectangle {
      objectName: "streamRectangle"
      /* ... */
      }
    /* ... */
    }
    

    //main.cpp:

    int main(int argc, char *argv[])
    {
      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
      QGuiApplication app(argc, argv);
      QQmlApplicationEngine engine;
    
      engine.load(QUrl(QStringLiteral("qrc:/MainWindow.qml")));
      if (engine.rootObjects().isEmpty())
        return -1;
    
      QObject *rootObject = engine.rootObjects().first();
      if (rootObject)
      {
        QObject *rect = rootObject->findChild<QObject*>("streamRectangle");
        if (rect)
        {
          std::cout << "Child item found" << std::endl;
          QWindow *window = qobject_cast<QWindow*>(rect);
          if (window)
          {
            std::cout << "Successfully retrieved stream window" << std::endl;
            WId wid = window->winId();
              if (wid)
              {
                std::cout << "Successfully retrieved WID!" << std::endl;
                // make use of the ID here
              }
          }
        }
      }
    
      return app.exec();
    }
    

    This compiles, however I get: qrc:/MainWindow.qml:27: ReferenceError: streamRectangle is not defined as an error message.
    A few searches later, I see that I'm supposed to add "streamRectangle" to the root context (?). I am, however, unable to do that successfully.

    Any thoughts on the issue? Help is greatly appreciated.


  • Moderators

    @Nikola-Ninkov said in [Windows] Retrieving a window handle of a control using objectName:

    ApplicationWindow {
    visible: true
    width: 1280
    height: 720

    Rectangle {
        anchors.fill: parent
        objectName: streamRectangle
    }
    

    }

    that is not what you wrote in the opening post!
    streamRectangle has to be a string

    ApplicationWindow {
        visible: true
        width: 1280
        height: 720
    
        Rectangle {
            anchors.fill: parent
            objectName: "streamRectangle"
        }
    
    }
    


  • You are doing something strange here. Once you found your rectangle by object name you can cast it to a QQuickItem* and use window method of this item.



  • @IntruderExcluder Thanks for your input. If I understand correctly, you are suggesting:

    QObject *rootObject = engine.rootObjects().first();
    if (rootObject)
      {
        QObject *rect = rootObject->findChild<QObject*>("streamRectangle");
        if (rect)
        {
          QWindow *window = qobject_cast<QQuickItem*>(rect)->window();
        /* ... */
        }
    }
    

    I am still getting qrc:/MainWindow.qml:27: ReferenceError: streamRectangle is not defined. How do I fix this?



  • We need more QML code to understand what happening.



  • @IntruderExcluder This is MainWindow.qml - the only QML code being loaded:

    import QtQuick 2.12
    import QtQuick.Controls 2.12
    
    ApplicationWindow {
        visible: true
        width: 1280
        height: 720
    
        Rectangle {
            anchors.fill: parent
            objectName: streamRectangle
        }
    
    }
    

    And here's main.cpp:

    #include <QtQuick>
    
    int main(int argc, char *argv[])
    {
      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
      QGuiApplication app(argc, argv);
      QQmlApplicationEngine engine;
    
      engine.load(QUrl(QStringLiteral("qrc:/MainWindow.qml")));
      if (engine.rootObjects().isEmpty())
        return -1;
    
      QObject *rootObject = engine.rootObjects().first();
      if (rootObject)
      {
        QObject *rect = rootObject->findChild<QObject*>("streamRectangle");
        if (rect)
        {
          QWindow *window = qobject_cast<QQuickItem*>(rect)->window();
          if (window)
          {
            WId wid = window->winId();
            if (wid)
            {
              // do something with wid
            }
          }
        }
      }
    
      return app.exec();
    }
    

  • Moderators

    @Nikola-Ninkov said in [Windows] Retrieving a window handle of a control using objectName:

    ApplicationWindow {
    visible: true
    width: 1280
    height: 720

    Rectangle {
        anchors.fill: parent
        objectName: streamRectangle
    }
    

    }

    that is not what you wrote in the opening post!
    streamRectangle has to be a string

    ApplicationWindow {
        visible: true
        width: 1280
        height: 720
    
        Rectangle {
            anchors.fill: parent
            objectName: "streamRectangle"
        }
    
    }
    


  • @J-Hilk I think I just sank through my office floor. It works now.

    As for the differences from the OP, I went back to the file and removed everything not directly relevant to the object I was targeting. Guess I also made the 0 IQ play with the quotation marks.

    Thank you very much.


Log in to reply