我编写了一个简单的pyqt5 + qml应用程序,该应用程序将绘制函数图。我试图在单击按钮时更改画布的背景颜色,但是什么也没有发生,这是代码。
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
class Plot(QObject):
def __init__(self):
QObject.__init__(self)
updCanv = pyqtSignal(arguments=['upd'])
@pyqtSlot()
def upd(self):
self.updCanv.emit()
if __name__ == "__main__":
import sys
# Create an instance of the application
sys.argv += ['--style', 'material']
app = QGuiApplication(sys.argv)
# Create QML engine
engine = QQmlApplicationEngine()
# Create a plot object
plot = Plot()
# And register it in the context of QML
engine.rootContext().setContextProperty("plot", plot)
# Load the qml file into the engine
engine.load("main.qml")
engine.quit.connect(app.quit)
sys.exit(app.exec_())
import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.2
ApplicationWindow {
visible: true
width: 640
height: 240
title: qsTr("Function plot")
Material.theme: Material.Dark
GridLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 9
columns: 4
rows: 4
rowSpacing: 10
columnSpacing: 10
Text {
color: "whitesmoke"
text: qsTr("Left bound")
}
TextField {
id: left_bound
}
Text {
color: "whitesmoke"
text: qsTr("Right bound")
}
TextField {
id: right_bound
}
ComboBox{
model: ['cos', 'sin', 'x^2']
}
Button {
height: 40
Layout.fillWidth: true
text: qsTr("Build plot")
onClicked: {
plot.upd(left_bound.text, right_bound.text)
}
}
Canvas {
id: canv
Layout.fillWidth: true
height: 500
Layout.columnSpan: 4
onPaint: {
var ctx = getContext("2d");
ctx.fillStyle = Qt.rgba(1, 1, 1, 1);
ctx.fillRect(0, 0, width, height);
}
}
}
Connections {
target: plot
onUpdCanv: {
onPaint: {
var ct = canv.getContext("2d");
ct.fillStyle = Qt.rgba(0, 0, 1, 1);
ct.fillRect(0, 0, width, height);
canv.requestPaint();
}
}
}
}
我该怎么办?我要更改绘图或选择另一个要显示的功能时如何更新画布,还需要添加功能来缩小/缩小绘图,可以用Canvas对象制作吗?
谢谢!
答案 0 :(得分:0)
我不了解Plot类的用法,似乎没有必要,因为您要做的只是转发它收到的信号。如果要更改颜色,则可以仅使用QML
直接进行更改,在以下示例中,每次按下按钮时都会生成随机颜色。
main.qml
import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.2
ApplicationWindow {
visible: true
width: 640
height: 240
title: qsTr("Function plot")
Material.theme: Material.Dark
property color plotColor : "blue"
onPlotColorChanged: canv.requestPaint()
GridLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 9
columns: 4
rows: 4
rowSpacing: 10
columnSpacing: 10
Text {
color: "whitesmoke"
text: qsTr("Left bound")
}
TextField {
id: left_bound
}
Text {
color: "whitesmoke"
text: qsTr("Right bound")
}
TextField {
id: right_bound
}
ComboBox{
model: ['cos', 'sin', 'x^2']
}
Button {
height: 40
Layout.fillWidth: true
text: qsTr("Build plot")
onClicked: plotColor = Qt.rgba(Math.random(),Math.random(),Math.random(),1);
}
Canvas {
id: canv
Layout.fillWidth: true
height: 500
Layout.columnSpan: 4
onPaint: {
var ctx = getContext("2d");
ctx.fillStyle = plotColor;
ctx.fillRect(0, 0, width, height);
}
}
}
}
如果要zoomIn / zoomOut,可以使用scale function,因此也可以实现各种图形的布局。
另一方面,我认为最简单的方法是使用模块QtCharts,您已经实现了所有此类任务。
如果没有必要,则不必在python / C ++端创建类,也就是说,如果您可以在QML
中进行所有操作,则它要简单得多,因此,我指出我认为不需要Plot类。
如果您发现Qt图表不够用,或者不想使用画布,并且对python更加熟悉,则可以使用QQuickPaintedItem
类来创建自己的画布。