gpt4 book ai didi

python - 将循环变化的 python 变量暴露给 QML

转载 作者:行者123 更新时间:2023-12-04 09:15:09 24 4
gpt4 key购买 nike

我正在尝试获取一个 python 变量并在 QML 中使用它。我的实现是创建一个按钮,单击该按钮时,将获取从我的程序生成的数据并将浮点值附加到线系列的 x 和 y。有什么建议?
这是我的程序中的一些代码,可以复制我的问题:

# ========================================================================  #
from math import exp


class ErrorFunction:
def firstPoint(self, param):
if param < 0:
return -self.firstPoint(-param)
else:
p = 0.47047
a = [0.3480242, -0.0958798, 0.7478556]
t = 1.0 / (1.0 + p * param)
return 1 - t * (a[0] + t * (a[1] + t * a[2])) * exp(-(param ** 2))

def successivePoint(self, param):
return 1 - self.firstPoint(param)
# ======================================================================== #
# ========================================================================  #
import os
import sys

from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtWidgets import QApplication

from ErrorFunction import ErrorFunction


class ErrorFunctionRunnable:
def __init__(self):
errorfunction = ErrorFunction()
n = 100
errorPoints = [(0, 0)] * n
for i in range(n):
x = i * 0.1 - 5.0
errorPoints[i] = (errorfunction.firstPoint(x), errorfunction.successivePoint(x))
print(errorPoints[i])


if __name__ == "__main__":
os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
app = QApplication(sys.argv)

engine = QQmlApplicationEngine()

engine.load(os.path.join(os.path.dirname(__file__), "gui.qml"))

if not engine.rootObjects():
sys.exit(-1)

sys.exit(app.exec_())
# ======================================================================== #
// ========================================================================  #
import QtQuick 2.0
import QtQuick.Controls 2.5
import QtQuick.Controls.Material 2.3
import QtCharts 2.3

ApplicationWindow {
id: applicationWindow
visible: true
width: 720
height: 780
title: qsTr("QML Test")
Material.background: Material.color(Material.Grey, Material.Shade900)

GroupBox {
id: groupBox
width: 114
anchors.top: parent.top
anchors.topMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0

Button {
id: button
x: 8
y: 0
width: 74
height: 48
text: qsTr("E_r")
font.pointSize: 10
Material.foreground: Material.color(Material.Grey, Material.Shade100)
Material.background: Material.color(Material.Grey, Material.Shade800)
onClicked: {
line.removeAllSeries()
/*
Run the "ErrorFunctionRunnable" init function to generate "errorPoints"
*/
}
}
}

GroupBox {
id: groupBox2
anchors.right: parent.right
anchors.rightMargin: 0
anchors.top: parent.top
anchors.topMargin: 0
anchors.left: parent.left
anchors.leftMargin: 114
anchors.bottom: parent.bottom
anchors.bottomMargin: 75

ChartView {
id: line
dropShadowEnabled: false
anchors.left: parent.left
anchors.leftMargin: 0
anchors.top: parent.top
anchors.topMargin: 0
anchors.right: parent.right
anchors.rightMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
theme: ChartView.ChartThemeDark
antialiasing: true

backgroundColor: Material.color(Material.Grey, Material.Shade900)
LineSeries {
name: "Marshak Wave"
/*
Update the line series with the points from "errorPoints"
*/
}
}
}

GroupBox {
id: groupBox1
y: 704
height: 76
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 114
anchors.bottom: parent.bottom
anchors.bottomMargin: 0


}

}
// ======================================================================== #

最佳答案

一个可能的解决方案是创建一个 QObject,通过一个方法向 QML 公开 QPointF 列表,此外必须更新轴的限制,如下所示:

import math
import os
import sys

from PySide2.QtCore import QObject, QPointF, Slot
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtWidgets import QApplication


class ErrorFunction:
def firstPoint(self, param):
if param < 0:
return -self.firstPoint(-param)
else:
p = 0.47047
a = [0.3480242, -0.0958798, 0.7478556]
t = 1.0 / (1.0 + p * param)
return 1 - t * (a[0] + t * (a[1] + t * a[2])) * math.exp(-(param ** 2))

def successivePoint(self, param):
return 1 - self.firstPoint(param)


class Bridge(QObject):
@Slot(result="QVariantList")
def produce(self):
f = ErrorFunction()
values = []
n = 100
for i in range(n):
x = i * 0.1 - 5.0
p = QPointF(f.firstPoint(x), f.successivePoint(x))
values.append(p)
return values


if __name__ == "__main__":
os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
app = QApplication(sys.argv)

bridge = Bridge()

engine = QQmlApplicationEngine()
engine.rootContext().setContextProperty("bridge", bridge)

engine.load(os.path.join(os.path.dirname(__file__), "gui.qml"))

if not engine.rootObjects():
sys.exit(-1)

sys.exit(app.exec_())
import QtQuick 2.0
import QtQuick.Controls 2.5
import QtQuick.Controls.Material 2.3
import QtCharts 2.3

ApplicationWindow {
id: applicationWindow
visible: true
width: 720
height: 780
title: qsTr("QML Test")
Material.background: Material.color(Material.Grey, Material.Shade900)

GroupBox {
id: groupBox
width: 114
anchors.top: parent.top
anchors.topMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0

Button {
id: button
x: 8
y: 0
width: 74
height: 48
text: qsTr("E_r")
font.pointSize: 10
Material.foreground: Material.color(Material.Grey, Material.Shade100)
Material.background: Material.color(Material.Grey, Material.Shade800)
onClicked: {
line.removePoints(0, line.count)
var x_min = line.axisX.min
var x_max = line.axisX.max
var y_min = line.axisY.min
var y_max = line.axisY.max

var values = bridge.produce()
for(var i in values){
line.append(values[i].x, values[i].y)
x_min = Math.min(x_min, values[i].x)
x_max = Math.max(x_max, values[i].x)
y_min = Math.min(y_min, values[i].y)
y_max = Math.max(y_max, values[i].y)
}
line.axisX.min = x_min
line.axisX.max = x_max
line.axisY.min = y_min
line.axisY.max = y_max
}
}
}

GroupBox {
id: groupBox2
anchors.fill: parent
anchors.rightMargin: 0
anchors.topMargin: 0
anchors.leftMargin: 114
anchors.bottomMargin: 75

ChartView {
id: view
dropShadowEnabled: false
anchors.fill: parent
anchors.margins: 0
theme: ChartView.ChartThemeDark
antialiasing: true

backgroundColor: Material.color(Material.Grey, Material.Shade900)
LineSeries {
id: line
name: "Marshak Wave"
}
}
}
GroupBox {
id: groupBox1
y: 704
height: 76
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 114
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
}
}
enter image description here
缺点是 QML 中的 for 循环,如果数据有很多元素,可能的优化是使用 replace 方法,但在 QML 中无法访问,因此必须将元素导出到 python:
import math
import os
import sys

from PySide2.QtCore import QObject, QPointF, Slot
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtWidgets import QApplication
from PySide2.QtCharts import QtCharts


class ErrorFunction:
def firstPoint(self, param):
if param < 0:
return -self.firstPoint(-param)
else:
p = 0.47047
a = [0.3480242, -0.0958798, 0.7478556]
t = 1.0 / (1.0 + p * param)
return 1 - t * (a[0] + t * (a[1] + t * a[2])) * math.exp(-(param ** 2))

def successivePoint(self, param):
return 1 - self.firstPoint(param)


class Bridge(QObject):
@Slot(QtCharts.QAbstractSeries)
def fill(self, series):
axis_x = series.property("axisX")
axis_y = series.property("axisY")
xmin = axis_x.min()
xmax = axis_x.max()
ymin = axis_y.min()
ymax = axis_y.max()
f = ErrorFunction()
values = []
n = 100
for i in range(n):
x = i * 0.1 - 5.0
xi = f.firstPoint(x)
yi = f.successivePoint(x)
p = QPointF(xi, yi)
xmin = min(xmin, xi)
xmax = max(xmax, xi)
ymin = min(ymin, yi)
ymax = max(ymax, yi)
values.append(p)
series.replace(values)
axis_x.setMin(xmin)
axis_x.setMax(xmax)
axis_y.setMin(ymin)
axis_y.setMax(ymax)


if __name__ == "__main__":
os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
app = QApplication(sys.argv)

bridge = Bridge()

engine = QQmlApplicationEngine()
engine.rootContext().setContextProperty("bridge", bridge)

engine.load(os.path.join(os.path.dirname(__file__), "gui.qml"))

if not engine.rootObjects():
sys.exit(-1)

sys.exit(app.exec_())
import QtQuick 2.0
import QtQuick.Controls 2.5
import QtQuick.Controls.Material 2.3
import QtCharts 2.3

ApplicationWindow {
id: applicationWindow
visible: true
width: 720
height: 780
title: qsTr("QML Test")
Material.background: Material.color(Material.Grey, Material.Shade900)

GroupBox {
id: groupBox
width: 114
anchors.top: parent.top
anchors.topMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0

Button {
id: button
x: 8
y: 0
width: 74
height: 48
text: qsTr("E_r")
font.pointSize: 10
Material.foreground: Material.color(Material.Grey, Material.Shade100)
Material.background: Material.color(Material.Grey, Material.Shade800)
onClicked: {
bridge.fill(line)
}
}
}

GroupBox {
id: groupBox2
anchors.fill: parent
anchors.rightMargin: 0
anchors.topMargin: 0
anchors.leftMargin: 114
anchors.bottomMargin: 75

ChartView {
id: view
dropShadowEnabled: false
anchors.fill: parent
anchors.margins: 0
theme: ChartView.ChartThemeDark
antialiasing: true

backgroundColor: Material.color(Material.Grey, Material.Shade900)
LineSeries {
id: line
name: "Marshak Wave"
}
}
}
GroupBox {
id: groupBox1
y: 704
height: 76
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 114
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
}
}

关于python - 将循环变化的 python 变量暴露给 QML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63257251/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com