扩展QML(高级)- 生日派对基础项目¶
这是使用生日派对示例来展示QML一些高级功能的6个示例系列中的第一个。下面解释的各种功能的代码基于这个生日派对项目,并依赖于基础教程中的一些材料。然后,这个简单的示例被扩展以说明下面解释的各种QML扩展。每个新扩展的完整代码可以在相应页面的末尾找到。
基础项目定义了Person
类和BirthdayParty
类,分别用于建模参与者和派对本身。
13
14@QmlElement
15class Person(QObject):
16 name_changed = Signal()
17 shoe_size_changed = Signal()
18
19 def __init__(self, parent=None):
20 super().__init__(parent)
21 self._name = ''
22 self._shoe_size = 0
23
24 @Property(str, notify=name_changed, final=True)
25 def name(self):
26 return self._name
27
28 @name.setter
29 def name(self, n):
30 if self._name != n:
31 self._name = n
32 self.name_changed.emit()
33
34 @Property(int, notify=shoe_size_changed, final=True)
35 def shoe_size(self):
36 return self._shoe_size
37
38 @shoe_size.setter
39 def shoe_size(self, s):
40 if self._shoe_size != s:
41 self._shoe_size = s
16
17@QmlElement
18class BirthdayParty(QObject):
19 host_changed = Signal()
20 guests_changed = Signal()
21
22 def __init__(self, parent=None):
23 super().__init__(parent)
24 self._host = None
25 self._guests = []
26
27 @Property(Person, notify=host_changed, final=True)
28 def host(self):
29 return self._host
30
31 @host.setter
32 def host(self, h):
33 if self._host != h:
34 self._host = h
35 self.host_changed.emit()
36
37 def guest(self, n):
38 return self._guests[n]
39
40 def guestCount(self):
41 return len(self._guests)
42
43 def appendGuest(self, guest):
44 self._guests.append(guest)
45 self.guests_changed.emit()
46
所有关于聚会的信息都可以存储在相应的QML文件中。
4import People
5
6BirthdayParty {
7 host: Person {
8 name: "Bob Jones"
9 shoe_size: 12
10 }
11 guests: [
12 Person { name: "Leo Hodges" },
13 Person { name: "Jack Smith" },
14 Person { name: "Anne Brown" }
15 ]
16}
main.py
文件创建了一个简单的 shell 应用程序,用于显示谁的生日以及谁被邀请参加他们的派对。
17
18app = QCoreApplication(sys.argv)
19engine = QQmlEngine()
20engine.addImportPath(Path(__file__).parent)
21component = QQmlComponent(engine)
应用程序输出以下聚会摘要:
"Bob Jones" is having a birthday!
They are inviting:
"Leo Hodges"
"Jack Smith"
"Anne Brown"
展望¶
以下部分将介绍如何通过使用继承和强制转换来添加对Boy
和Girl
参与者的支持,而不仅仅是Person
,如何利用默认属性将派对的参与者隐式分配为客人,如何将属性分配为组而不是逐个分配,如何使用附加对象来跟踪受邀客人的回复,如何使用属性值源随时间显示生日快乐歌的歌词,以及如何将第三方对象暴露给QML。
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations
"""PySide6 port of the
qml/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project example from Qt v6.x"""
from pathlib import Path
import sys
from PySide6.QtCore import QCoreApplication
from PySide6.QtQml import QQmlComponent, QQmlEngine
from person import Person # noqa: F401
from birthdayparty import BirthdayParty # noqa: F401
app = QCoreApplication(sys.argv)
engine = QQmlEngine()
engine.addImportPath(Path(__file__).parent)
component = QQmlComponent(engine)
component.loadFromModule("People", "Main")
party = component.create()
if not party:
print(component.errors())
del engine
sys.exit(-1)
host = party.host
print(f"{host.name} is having a birthday!\nThey are inviting:")
for g in range(party.guestCount()):
name = party.guest(g).name
print(f" {name}")
del engine
sys.exit(0)
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations
from PySide6.QtCore import QObject, Property, Signal
from PySide6.QtQml import QmlElement, ListProperty
from person import Person
# To be used on the @QmlElement decorator
# (QML_IMPORT_MINOR_VERSION is optional)
QML_IMPORT_NAME = "People"
QML_IMPORT_MAJOR_VERSION = 1
@QmlElement
class BirthdayParty(QObject):
host_changed = Signal()
guests_changed = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self._host = None
self._guests = []
@Property(Person, notify=host_changed, final=True)
def host(self):
return self._host
@host.setter
def host(self, h):
if self._host != h:
self._host = h
self.host_changed.emit()
def guest(self, n):
return self._guests[n]
def guestCount(self):
return len(self._guests)
def appendGuest(self, guest):
self._guests.append(guest)
self.guests_changed.emit()
guests = ListProperty(Person, appendGuest, notify=guests_changed, final=True)
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations
from PySide6.QtCore import QObject, Property, Signal
from PySide6.QtQml import QmlElement
# To be used on the @QmlElement decorator
# (QML_IMPORT_MINOR_VERSION is optional)
QML_IMPORT_NAME = "People"
QML_IMPORT_MAJOR_VERSION = 1
@QmlElement
class Person(QObject):
name_changed = Signal()
shoe_size_changed = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self._name = ''
self._shoe_size = 0
@Property(str, notify=name_changed, final=True)
def name(self):
return self._name
@name.setter
def name(self, n):
if self._name != n:
self._name = n
self.name_changed.emit()
@Property(int, notify=shoe_size_changed, final=True)
def shoe_size(self):
return self._shoe_size
@shoe_size.setter
def shoe_size(self, s):
if self._shoe_size != s:
self._shoe_size = s
self.shoe_size_changed.emit()
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import People
BirthdayParty {
host: Person {
name: "Bob Jones"
shoe_size: 12
}
guests: [
Person { name: "Leo Hodges" },
Person { name: "Jack Smith" },
Person { name: "Anne Brown" }
]
}
module People
typeinfo coercion.qmltypes
Main 1.0 Main.qml