更改画布颜色pyqt5 qml

时间:2018-07-13 15:47:27

标签: python canvas pyqt qml pyqt5

我编写了一个简单的pyqt5 + qml应用程序,该应用程序将绘制函数图。我试图在单击按钮时更改画布的背景颜色,但是什么也没有发生,这是代码。

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();
        }

    }
}
}

我该怎么办?我要更改绘图或选择另一个要显示的功能时如何更新画布,还需要添加功能来缩小/缩小绘图,可以用Canvas对象制作吗?

谢谢!

1 个答案:

答案 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类来创建自己的画布。