Ошибка при получении корневого объекта из QQmlApplicationEngine в Component.OnCompleted

#python #qt #qml #pyside2 #qqmlapplicationengine

#python #qt #qml #pyside2 #qqmlapplicationengine

Вопрос:

Я пытаюсь получить корневой объект после завершения window, но получаю сообщение об ошибке:

 QmlObj = self.engine.rootObjects()[0]
 

Ошибка: индекс списка вне диапазона

Странно то, что он работает, когда я пытаюсь вызвать foo.init_window() после нажатия на область мыши.

Вот мой код на python:

main.py

 from PySide2.QtWidgets import QApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QObject, QUrl, Slot

import sys
import win32gui

flag = False


class Foo(QObject):
    def __init__(self):
        super().__init__()
        self.engine = QQmlApplicationEngine()

    @Slot()
    def init_window(self):
        global flag
        if not flag:
            QmlObj = self.engine.rootObjects()[0]
            desk = win32gui.FindWindow("Progman", "Program Manager")
            print(desk)
            sndWnd = win32gui.FindWindowEx(desk, 0, "SHELLDLL_DefView", None)
            print(sndWnd)
            targetWnd = win32gui.FindWindowEx(sndWnd,
                                              0, "SysListView32", "FolderView")
            print(targetWnd)
            win32gui.SetParent((int)(QmlObj.winId()), targetWnd)
            flag = True


if __name__ == "__main__":
    app = QApplication(sys.argv)
    foo = Foo()

    foo.engine.rootContext().setContextProperty("foo", foo)
    foo.engine.load(QUrl("main.qml"))
    # win = foo.engine.rootObjects()[0]
    # win.show()

    if not foo.engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

 

Вот .файл qml:

main.qml

 import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
    width: 200
    height: 100
    visible: true
    //flags: Qt.FramelessWindowHint
    //flags: Qt.WindowStaysOnBottomHint
    //flags: Qt.WindowMinMaxButtonsHint

    Rectangle {
        anchors.fill: parent
        color: "red"

        Component.onCompleted: foo.init_window()

        MouseArea {
            anchors.fill: parent
            onClicked: foo.init_window()
        }

        Text {
            anchors.centerIn: parent
            text: "Hello, World!"
        }

        Button {
            text: "Ok"
            onClicked: {
                console.log("OK Button clicked....")
            }
        }
    }
}
 

Ответ №1:

Проблема в том, что в Component.onCompleted окне (RootObject) завершена сборка, но список движков не был обновлен. Решение состоит в том, чтобы вызвать init_window мгновение спустя с помощью Qt.callLater() :

 Component.onCompleted: Qt.callLater(foo.init_window)