场景图绘制项目示例#
展示如何基于QPainter实现自定义场景图项目。
绘制项目示例展示如何使用QML场景图框架通过QPainter实现自定义场景图项目。
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import TextBalloonPlugin
Item {
height: 480
width: 320
//! [0]
ListModel {
id: balloonModel
ListElement {
balloonWidth: 200
}
ListElement {
balloonWidth: 120
}
}
ListView {
anchors.bottom: controls.top
anchors.bottomMargin: 2
anchors.top: parent.top
id: balloonView
delegate: TextBalloon {
anchors.right: index % 2 == 0 ? undefined : balloonView.contentItem.right
height: 60
rightAligned: index % 2 == 0 ? false : true
width: balloonWidth
}
model: balloonModel
spacing: 5
width: parent.width
}
//! [0]
//! [1]
Rectangle {
id: controls
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.margins: 1
anchors.right: parent.right
border.width: 2
color: "white"
height: parent.height * 0.15
Text {
anchors.centerIn: parent
text: "Add another balloon"
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
balloonModel.append({
"balloonWidth": Math.floor(
Math.random(
) * 200 + 100)
})
balloonView.positionViewAtIndex(balloonView.count - 1,
ListView.End)
}
onEntered: {
parent.color = "#8ac953"
}
onExited: {
parent.color = "white"
}
}
}
//! [1]
}
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from argparse import ArgumentParser, RawTextHelpFormatter
from pathlib import Path
import sys
from PySide6.QtGui import QPainter, QBrush, QColor
from PySide6.QtWidgets import QApplication
from PySide6.QtQml import QmlElement, QQmlDebuggingEnabler
from PySide6.QtCore import QUrl, Property, Signal, Qt, QPointF
from PySide6.QtQuick import QQuickPaintedItem, QQuickView
QML_IMPORT_NAME = "TextBalloonPlugin"
QML_IMPORT_MAJOR_VERSION = 1
QML_IMPORT_MINOR_VERSION = 0 # Optional
@QmlElement
class TextBalloon(QQuickPaintedItem):
rightAlignedChanged = Signal()
def __init__(self, parent=None):
self._rightAligned = False
super().__init__(parent)
@Property(bool, notify=rightAlignedChanged)
def rightAligned(self):
return self._rightAligned
@rightAligned.setter
def rightAligned(self, value):
self._rightAligned = value
self.rightAlignedChanged.emit()
def paint(self, painter: QPainter):
brush = QBrush(QColor("#007430"))
painter.setBrush(brush)
painter.setPen(Qt.NoPen)
painter.setRenderHint(QPainter.Antialiasing)
itemSize = self.size()
painter.drawRoundedRect(0, 0, itemSize.width(), itemSize.height() - 10, 10, 10)
if self.rightAligned:
points = [
QPointF(itemSize.width() - 10.0, itemSize.height() - 10.0),
QPointF(itemSize.width() - 20.0, itemSize.height()),
QPointF(itemSize.width() - 30.0, itemSize.height() - 10.0),
]
else:
points = [
QPointF(10.0, itemSize.height() - 10.0),
QPointF(20.0, itemSize.height()),
QPointF(30.0, itemSize.height() - 10.0),
]
painter.drawConvexPolygon(points)
if __name__ == "__main__":
argument_parser = ArgumentParser(description="Scene Graph Painted Item Example",
formatter_class=RawTextHelpFormatter)
argument_parser.add_argument("-qmljsdebugger", action="store",
help="Enable QML debugging")
options = argument_parser.parse_args()
if options.qmljsdebugger:
QQmlDebuggingEnabler.enableDebugging(True)
app = QApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
qml_file = Path(__file__).parent / "main.qml"
view.setSource(QUrl.fromLocalFile(qml_file))
if view.status() == QQuickView.Error:
sys.exit(-1)
view.show()
sys.exit(app.exec())