python - 使用 qml 中的元素显示的 python 中的数组
问题描述
我应该用 qml 显示一些矩形。这些 Rectangle{} 的位置取决于 x=array[i][0] 和 y=array[i][1],其数量取决于 array.lenght()。
qml 中的数组应该等于 Python 中的 self.__rectanglePos
所以我需要一种方法来在不同的位置和不同的数量上绘制矩形,这取决于数组。
我怎样才能做到这一点?
_____.py
class NN(QObject):
def __init__(self):
QObject.__init__(self)
self.__rectanglePos = [] #each element contains:[x,y,orientation 360°]
#signals
rectanglePosChanged = Signal(type(self.__rectanglePos))
@Slot()
def rects(self):
self.rectanglePosChanged.emit(self.__rectanglePos)
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
qmlRegisterType(NN, 'gnn', 1, 0, 'NN')
engine.load(QUrl.fromLocalFile(gnn.qml))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
这在 qml 中不起作用:________.qml
#[...]
import gnn 1.0
ApplicationWindow {
ListView{
id: rect
function f(){
for (var i = 0; i < array.lenght(); ++i){
Rectangle {
x: array[i][0]
y: array[i][1]
}
}
}
}
MouseArea{
onClicked: rects()
}
NN{
id: nn
signal getRectangles(var array) // not working
Component.onCompleted: {
nn.rectanglePosChanged.connect(getRectangles)
}
}
Connections {
target: nn
onGetRectangles: {
}
}
}
解决方案
您的代码有很多错误,例如您想访问类的属性:self.__rectanglePos)
这仅在从创建类之前执行的部分代码创建对象时才有意义:rectanglePosChanged = Signal(type(self.__rectanglePos))
,因此我将避免指出您的错误除了我的解决方案所必需的之外。
如果您想将信息作为添加、替换或删除项目的列表发送,那么最好使用模型,因为它会根据更改通知您。在这种情况下,为了简单起见,我使用 QStandardItemModel,因此元素的每个部分作为“x”和“y”都将通过角色访问。
在 QML 的情况下,由于您想将 Rectangles 放置在任何位置,因此使用 ListView 不是正确的选择,因为此视图限制了位置,而您必须使用 Repeater。
主文件
import os
import sys
from PySide2 import QtCore, QtGui, QtQml
XRole = QtCore.Qt.UserRole + 1000
YRole = QtCore.Qt.UserRole + 1001
AngleRole = QtCore.Qt.UserRole + 1002
class RectangleManager(QtCore.QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.m_model = QtGui.QStandardItemModel(self)
roles = {XRole: b"x", YRole: b"y", AngleRole: b"angle"}
self.m_model.setItemRoleNames(roles)
@QtCore.Property(QtCore.QObject, constant=True)
def model(self):
return self.m_model
@QtCore.Slot(float, float, float)
def add_rectangle(self, x, y, angle):
it = QtGui.QStandardItem()
it.setData(x, XRole)
it.setData(y, YRole)
it.setData(angle, AngleRole)
self.model.appendRow(it)
@QtCore.Slot()
def clear_rectangles(self):
self.model.clear()
def main(args):
app = QtGui.QGuiApplication(args)
manager = RectangleManager()
import random
for _ in range(10):
manager.add_rectangle(
random.randint(0, 500), random.randint(0, 500), random.randint(0, 360)
)
engine = QtQml.QQmlApplicationEngine()
engine.rootContext().setContextProperty("rectangle_manager", manager)
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "main.qml")
engine.load(QtCore.QUrl.fromLocalFile(filename))
if not engine.rootObjects():
return -1
ret = app.exec_()
return ret
if __name__ == "__main__":
sys.exit(main(sys.argv))
main.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
id: root
width: 640
height: 480
visible: true
Repeater{
model: rectangle_manager.model
Rectangle{
x: model.x
y: model.y
rotation: model.angle
width: 100
height: 100
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
}
推荐阅读
- d3.js - D3 - 数据更改后更新单个网格线
- javascript - 调用者上下文中的 Javascript 调用方法
- elasticsearch - 如何在 Kibana 中的字段上执行算术函数?
- xamarin.mac - 有没有办法让 Xamarin.Mac 应用程序隐藏它的窗口?
- r - How to get marginal effects for categorical variables in mlogit?
- java - Invert Map with list value Map
> to Map in Java 8 - kotlin - Kotlin 扩展函数 - Any 之间的区别?和通用 T?
- python -
while uploading large file via remote webdriver - html - 有什么方法可以在导航器中预览 .msg 文件?
- groovy - sed command won't replace my string when executed form Jenkins