#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)