QQmlApplicationEngine 列表索引超出范围问题
QQmlApplicationEngine list index out of range issue
我正在尝试 运行 来自这个 website 的最后 2 个示例并以
root = engine.rootObjects()[0] # type: QObject IndexError: list index out of range
两个示例的错误(根布局的信号连接)(其他 qml 文件的信号连接)
如果有帮助,我将所有示例文件放在同一目录级别并将导入语句更改为 Pyside6(来自 PySide6.QtCore...)而不是 PySide2。如果它更容易看到,我还添加了我的代码版本:
main.py:
import sys
from PySide6.QtCore import *
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
def say(s):
print(s)
if __name__ == '__main__':
app = QApplication()
engine = QQmlApplicationEngine()
engine.load(QUrl.fromLocalFile('main.qml'))
# Get the root object.
root = engine.rootObjects()[0] # type: QObject
# Find the target object. Since our target object is Window, which is the root object. So use it directly.
target_view = root
# Bind signal.
target_view.say.connect(say) # The former one is the signal of qml, and the latter one is from Python
# say() method.
sys.exit(app.exec())
main.qml:
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Window 2.12
Window {
visible: true
width: 600; height: 400
signal say(string s)
Button {
text: "hello"
onClicked: say(text)
}
}
错误的可能原因是:
- .qml 的路径不正确,因此未加载.qml。
- .qml 的加载并不像您假设的那样同步。
- .qml 有一些错误(例如语法)
综合以上,解决方案是:
import os
import sys
from pathlib import Path
from PySide6.QtCore import QCoreApplication, Qt, QUrl
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
CURRENT_DIRECTORY = Path(__file__).resolve().parent
def say(s):
print(s)
if __name__ == "__main__":
app = QApplication()
engine = QQmlApplicationEngine()
filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
url = QUrl.fromLocalFile(filename)
def handle_object_created(obj, obj_url):
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
else:
root = engine.rootObjects()[0]
target_view = root
target_view.say.connect(say)
engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)
engine.load(url)
sys.exit(app.exec())
但无论如何我不喜欢使用 rootObjects 而是导出 QObject:
import os
import sys
from pathlib import Path
from PySide6.QtCore import QCoreApplication, QObject, Qt, QUrl, Signal
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
CURRENT_DIRECTORY = Path(__file__).resolve().parent
class Helper(QObject):
say = Signal(str)
def say(s):
print(s)
if __name__ == "__main__":
app = QApplication()
engine = QQmlApplicationEngine()
helper = Helper()
helper.say.connect(say)
engine.rootContext().setContextProperty("helper", helper)
filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
url = QUrl.fromLocalFile(filename)
def handle_object_created(obj, obj_url):
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)
engine.load(url)
sys.exit(app.exec())
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Window 2.12
Window {
visible: true
width: 600
height: 400
Button {
text: "hello"
onClicked: helper.say(text)
}
}
我正在尝试 运行 来自这个 website 的最后 2 个示例并以
root = engine.rootObjects()[0] # type: QObject IndexError: list index out of range
两个示例的错误(根布局的信号连接)(其他 qml 文件的信号连接)
如果有帮助,我将所有示例文件放在同一目录级别并将导入语句更改为 Pyside6(来自 PySide6.QtCore...)而不是 PySide2。如果它更容易看到,我还添加了我的代码版本:
main.py:
import sys
from PySide6.QtCore import *
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
def say(s):
print(s)
if __name__ == '__main__':
app = QApplication()
engine = QQmlApplicationEngine()
engine.load(QUrl.fromLocalFile('main.qml'))
# Get the root object.
root = engine.rootObjects()[0] # type: QObject
# Find the target object. Since our target object is Window, which is the root object. So use it directly.
target_view = root
# Bind signal.
target_view.say.connect(say) # The former one is the signal of qml, and the latter one is from Python
# say() method.
sys.exit(app.exec())
main.qml:
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Window 2.12
Window {
visible: true
width: 600; height: 400
signal say(string s)
Button {
text: "hello"
onClicked: say(text)
}
}
错误的可能原因是:
- .qml 的路径不正确,因此未加载.qml。
- .qml 的加载并不像您假设的那样同步。
- .qml 有一些错误(例如语法)
综合以上,解决方案是:
import os
import sys
from pathlib import Path
from PySide6.QtCore import QCoreApplication, Qt, QUrl
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
CURRENT_DIRECTORY = Path(__file__).resolve().parent
def say(s):
print(s)
if __name__ == "__main__":
app = QApplication()
engine = QQmlApplicationEngine()
filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
url = QUrl.fromLocalFile(filename)
def handle_object_created(obj, obj_url):
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
else:
root = engine.rootObjects()[0]
target_view = root
target_view.say.connect(say)
engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)
engine.load(url)
sys.exit(app.exec())
但无论如何我不喜欢使用 rootObjects 而是导出 QObject:
import os
import sys
from pathlib import Path
from PySide6.QtCore import QCoreApplication, QObject, Qt, QUrl, Signal
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
CURRENT_DIRECTORY = Path(__file__).resolve().parent
class Helper(QObject):
say = Signal(str)
def say(s):
print(s)
if __name__ == "__main__":
app = QApplication()
engine = QQmlApplicationEngine()
helper = Helper()
helper.say.connect(say)
engine.rootContext().setContextProperty("helper", helper)
filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
url = QUrl.fromLocalFile(filename)
def handle_object_created(obj, obj_url):
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)
engine.load(url)
sys.exit(app.exec())
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Window 2.12
Window {
visible: true
width: 600
height: 400
Button {
text: "hello"
onClicked: helper.say(text)
}
}