扩展QML(高级)- 分组属性#
这是关于生日派对的一系列6个示例的第4个,用于使用生日派对的示例来演示的一些QML的高级功能。
需要更多关于客人鞋子的信息。除了尺寸外,我们还想存储鞋子的颜色、品牌和价格。此类信息存储在ShoeDescription
类中。
14@QmlAnonymous
15class ShoeDescription(QObject):
16 brand_changed = Signal()
17 size_changed = Signal()
18 price_changed = Signal()
19 color_changed = Signal()
20
21 def __init__(self, parent=None):
22 super().__init__(parent)
23 self._brand = ''
24 self._size = 0
25 self._price = 0
26 self._color = QColor()
27
28 @Property(str, notify=brand_changed, final=True)
29 def brand(self):
30 return self._brand
31
32 @brand.setter
33 def brand(self, b):
34 if self._brand != b:
35 self._brand = b
36 self.brand_changed.emit()
37
38 @Property(int, notify=size_changed, final=True)
39 def size(self):
40 return self._size
41
42 @size.setter
43 def size(self, s):
44 if self._size != s:
45 self._size = s
46 self.size_changed.emit()
47
48 @Property(float, notify=price_changed, final=True)
49 def price(self):
50 return self._price
51
52 @price.setter
53 def price(self, p):
54 if self._price != p:
55 self._price = p
56 self.price_changed.emit()
57
58 @Property(QColor, notify=color_changed, final=True)
59 def color(self):
60 return self._color
61
62 @color.setter
63 def color(self, c):
64 if self._color != c:
65 self._color = c
66 self.color_changed.emit()
现在每个人有两个属性,一个是name
,另一个是鞋描述shoe
。
69@QmlAnonymous
70class Person(QObject):
71 name_changed = Signal()
72
73 def __init__(self, parent=None):
74 super().__init__(parent)
75 self._name = ''
76 self._shoe = ShoeDescription()
77
78 @Property(str, notify=name_changed, final=True)
79 def name(self):
80 return self._name
81
82 @name.setter
83 def name(self, n):
84 if self._name != n:
85 self._name = n
86 self.name_changed.emit()
87
88 @Property(ShoeDescription, final=True)
89 def shoe(self):
90 return self._shoe
指定鞋描述的每个元素的值是可行的,但有点冗余。
26 Girl {
27 name: "Anne Brown"
28 shoe.size: 7
29 shoe.color: "red"
30 shoe.brand: "Job Macobs"
31 shoe.price: 699.99
32 }
分组属性提供了更优雅的方式来分配这些属性。而不是逐个属性分配值,可以将个别值作为一个组传递给shoe
属性,使代码更易于阅读。无需更改即可启用此功能,因为它对所有QML默认可用。
9 host: Boy {
10 name: "Bob Jones"
11 shoe { size: 12; color: "white"; brand: "Bikey"; price: 90.0 }
12 }
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
"""PySide6 port of the
qml/examples/qml/tutorials/extending-qml-advanced/advanced4-Grouped-properties 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 Boy, Girl # noqa: F401
from birthdayparty import BirthdayParty # noqa: F401
if __name__ == '__main__':
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!")
if isinstance(host, Boy):
print("He is inviting:")
else:
print("She is inviting:")
best_shoe = None
for g in range(party.guestCount()):
guest = party.guest(g)
name = guest.name
print(f" {name}")
if not best_shoe or best_shoe.shoe.price < guest.shoe.price:
best_shoe = guest
if best_shoe:
print(f"{best_shoe.name} is wearing the best shoes!")
del engine
sys.exit(0)
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from PySide6.QtCore import QObject, ClassInfo, 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
@ClassInfo(DefaultProperty="guests")
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) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from PySide6.QtCore import QObject, Property, Signal
from PySide6.QtGui import QColor
from PySide6.QtQml import QmlAnonymous, QmlElement
# To be used on the @QmlElement decorator
# (QML_IMPORT_MINOR_VERSION is optional)
QML_IMPORT_NAME = "People"
QML_IMPORT_MAJOR_VERSION = 1
@QmlAnonymous
class ShoeDescription(QObject):
brand_changed = Signal()
size_changed = Signal()
price_changed = Signal()
color_changed = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self._brand = ''
self._size = 0
self._price = 0
self._color = QColor()
@Property(str, notify=brand_changed, final=True)
def brand(self):
return self._brand
@brand.setter
def brand(self, b):
if self._brand != b:
self._brand = b
self.brand_changed.emit()
@Property(int, notify=size_changed, final=True)
def size(self):
return self._size
@size.setter
def size(self, s):
if self._size != s:
self._size = s
self.size_changed.emit()
@Property(float, notify=price_changed, final=True)
def price(self):
return self._price
@price.setter
def price(self, p):
if self._price != p:
self._price = p
self.price_changed.emit()
@Property(QColor, notify=color_changed, final=True)
def color(self):
return self._color
@color.setter
def color(self, c):
if self._color != c:
self._color = c
self.color_changed.emit()
@QmlAnonymous
class Person(QObject):
name_changed = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self._name = ''
self._shoe = ShoeDescription()
@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(ShoeDescription, final=True)
def shoe(self):
return self._shoe
@QmlElement
class Boy(Person):
def __init__(self, parent=None):
super().__init__(parent)
@QmlElement
class Girl(Person):
def __init__(self, parent=None):
super().__init__(parent)
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import People
BirthdayParty {
host: Boy {
name: "Bob Jones"
shoe { size: 12; color: "white"; brand: "Bikey"; price: 90.0 }
}
Boy {
name: "Leo Hodges"
shoe { size: 10; color: "black"; brand: "Thebok"; price: 59.95 }
}
Boy { name: "Jack Smith"
shoe {
size: 8
color: "blue"
brand: "Luma"
price: 19.95
}
}
Girl {
name: "Anne Brown"
shoe.size: 7
shoe.color: "red"
shoe.brand: "Job Macobs"
shoe.price: 699.99
}
}
module People
typeinfo coercion.qmltypes
Main 1.0 Main.qml