QML:QPainterPath的等价物是什么?

时间:2017-11-30 09:15:12

标签: c++ qt qml qt5 qpainterpath

为了将用C ++编写的一个GUI界面与Qt库转换为QML,我将在QML中找到QPainterPath的替代方法。实际上,目前,在GUI界面中绘制了一堆形状,并且当某些事件发生时,C ++代码会修改这些对象的颜色。 QPainterPath对象用于存储这些形状。

如果你能告诉我如何在QML画布中绘制两个矩形对象,然后如何在C ++代码中修改它们的填充颜色,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

正如我在评论中所说,一个选项可能是Canvas,它有类似于QPainterPath的方法。在下一部分中,我将展示一个示例,其中颜色可以通过生成随机颜色并由QTimer调用的方法从C ++更改:

<强>的main.cpp

#include <QColor>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTime>
#include <QTimer>

class ColorProvider: public QObject{
    Q_OBJECT
    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:

    QColor color() const{
        return mColor;
    }
    void setColor(const QColor &color){
        if(color == mColor)
            return;
        mColor = color;
        emit colorChanged(mColor);
    }

    Q_INVOKABLE void randomColor(){
        qsrand((uint)QTime::currentTime().msec());
        setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
    }

signals:
    void colorChanged(const QColor &color);
private:
    QColor mColor;
};

#include "main.moc"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    ColorProvider obj;

    QTimer timer;
    QObject::connect(&timer, &QTimer::timeout, &obj, &ColorProvider::randomColor);
    timer.start(100);

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("colorProvider", &obj);
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

<强> main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Canvas {
        id:canvas
        anchors.fill: parent
        onPaint:{
            var ctx = canvas.getContext('2d');
            ctx.lineWidth = 4
            ctx.fillStyle = "orange"
            ctx.strokeStyle = "red"
            ctx.fillRect(50, 40, 100, 100)
            ctx.stroke()
            ctx.fill()

            ctx.lineWidth = 10
            ctx.fillStyle = colorProvider.color
            ctx.fillRect(150, 150, 300, 300)
            ctx.stroke()
            ctx.fill()

            ctx.roundedRect(20, 20, 40, 40, 10, 10)
        }
    }

    Connections {
        target: colorProvider
        onColorChanged: canvas.requestPaint()
    }
}

完整示例可在以下link中找到。

答案 1 :(得分:0)

我现在在实施这个例子时遇到了一些麻烦。这是我的班级定义:

class ColorZones : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<QVariant> ColorZones READ getZoneColor NOTIFY zoneColorChanged) 

public:
    explicit ColorZones(QObject *parent = nullptr);
    QList<QVariant> getZoneColor() const {return _zonesColor;}
    void setZoneColor(const int zone, const QColor color);

signals:
    void zoneColorChanged();//QList<QVariant>);

private:
    QList<QVariant> _zonesColor;

};

以下是构造函数和setZoneColor函数的实现:

ColorZones::ColorZones(QObject *parent) : _zonesColor{QColor("orange"),QColor("grey"),QColor("grey"),QColor("grey"),QColor("grey"),QColor("grey")}
{

}

void ColorZones::setZoneColor(const int zone,const QColor color)
{
  ROS_INFO("The color was set");
  _zonesColor[zone] = color;
  emit zoneColorChanged();//_zonesColor);
}

然后,在主应用程序的构造函数中,我有那些代码行:

ColorZones *color_zones = new ColorZones; 

this->rootContext()->setContextProperty("ColorZones", color_zones); 

this->load(QUrl(QStringLiteral("qrc:/window1.qml")));

这是.qml文件:

import QtQuick 2.0
import QtQuick.Controls 1.4



Rectangle{
    id: zones
    width : 600; height : 600
    color : "transparent"
    border.color: "black"
        border.width: 2
    radius: 10
    objectName : "h_zones"
    visible : true
    Canvas {

        id:canvas
            anchors.fill: parent
        onPaint:{
            var ctx = canvas.getContext('2d');
            ctx.lineWidth = 2
            ctx.strokeStyle = "black"



            //ZONE 0
            ctx.fillStyle = ColorZones.getZoneColor[1]

            ctx.beginPath()
            ctx.moveTo(310,301)
            ctx.arcTo(10,1,600,600,65,50)
            ctx.closePath()

            ctx.stroke()    
            ctx.fill()  

            ctx.moveTo(310,181)
            ctx.lineTo(310,301)


            ctx.fill()
            ctx.stroke()

            //ZONE 1
            ctx.fillStyle = ColorZones.getZoneColor[1]

            ctx.beginPath()
            ctx.moveTo(304,304)
            ctx.lineTo(297,272)
            ctx.lineTo(189,164)
            ctx.lineTo(164,189)
            ctx.lineTo(272,297)
            ctx.closePath()

            ctx.fill()
            ctx.stroke

            //ZONE 2
            ctx.fillStyle = "orange"

            ctx.beginPath()
            ctx.moveTo(181,310)
            ctx.lineTo(301,310)
            ctx.closePath()

            ctx.beginPath()
            ctx.moveTo(301,310)
            ctx.lineTo(274,292)
            ctx.lineTo(121,292)
            ctx.lineTo(121,328)
            ctx.lineTo(274,328)
            ctx.closePath();

            ctx.fill()
            ctx.stroke

            //ZONE 3
            ctx.fillStyle = "blue"

            ctx.beginPath()
            ctx.moveTo(310,319)
            ctx.lineTo(328,346)
            ctx.lineTo(328,499)
            ctx.lineTo(292,499)
            ctx.lineTo(292,346)
            ctx.closePath()

            ctx.fill()
            ctx.stroke
            //ZONE 4
            ctx.fillStyle = "blue"
            ctx.beginPath()
            ctx.moveTo(439,310)
            ctx.lineTo(319,310)
            ctx.closePath()

            ctx.beginPath()
            ctx.moveTo(319,310)
            ctx.lineTo(346,292)
            ctx.lineTo(499,292)
            ctx.lineTo(499,328)
            ctx.lineTo(346,328)
            ctx.closePath()

            ctx.fill()
            ctx.stroke
            //ZONE 5
            ctx.fillStyle = "green"

            ctx.beginPath()
            ctx.moveTo(316,304)
            ctx.lineTo(323,272)
            ctx.lineTo(431,164)
            ctx.lineTo(456,189)
            ctx.lineTo(348,297)
            ctx.closePath()

            ctx.fill()
            ctx.stroke
        }
    }

        Connections {
               target: ColorZones //property
               onZoneColorChanged: canvas.requestPaint()
       }

然而,有两件事情不起作用:

  1. 当我调用setZoneColor时,qml应用程序永远不会收到信号(因此它不会重绘画布)
  2. TypeError:无法读取未定义的属性“1”
  3. 我无法弄清楚发生了什么?