Issue
I writing the simple pyqt5+qml application that will draw a function plot. I'm trying to change the background color of the canvas on click of the button, but nothing happens, here is the code.
main.py
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_())
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
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();
}
}
}
}
What can I do with it? How can I update the canvas when I want to change plot or choose another function to show, also I'll need to add function to zoom/out the plot, Is it possible to make with Canvas object?
Thank you!
Solution
I do not understand the use of the Plot class, it seems unnecessary because the only thing you do is to forward the signal it receives. If you want to change the color you can do it directly using only QML
, in the following example random colors are generated each time the button is pressed.
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);
}
}
}
}
If you want to zoomIn/zoomOut you can use the scale function, so you could also implement the layout of various graphics.
On the other hand I think that the simplest thing is to use the module QtCharts, you have already implemented all that kind of tasks.
If it is not necessary you do not create classes on the python/C++ side, that is, if you can do everything in QML
it is much simpler, so I indicate that I do not see the need for the Plot class.
If you see that Qt Charts is not enough, or you do not want to use canvas and you feel more familiar with python you could create your own canvas using the QQuickPaintedItem
class.
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.