如何重绘自定义QQuickItem

时间:2017-04-21 10:32:21

标签: c++ qt qml qt5 qtquick2

我通过扩展QQuickItem并覆盖updatePaintNode()功能创建了自定义QML元素。我在我的应用程序上绘制了两行,这些行将根据在应用程序左侧添加的块大小进行扩展或缩小。此块可以在小型和大型模式下添加,可以通过选择顶部栏上的按钮来删除。

这是我的代码:

line.cpp

#include <QSGGeometry>
#include <QSGGeometryNode>
#include <qsgnode.h>
#include <qsgflatcolormaterial.h>
#include "line.h"

Lines::Lines(QQuickItem *parent) : QQuickItem(parent) {
    setFlag(QQuickItem::ItemHasContents, true);
}

Lines::~Lines() {}

QSGNode *Lines::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) {
    QSGGeometryNode *node = NULL;
    QSGGeometry *geometry = NULL;
    QSGGeometry::Point2D *vertices;
    QSGFlatColorMaterial *material;
    int points = 0;
    int lineHeight = 0;
    int ys = 0;
    int xs;
    int xe;

    points = width();

    if (!oldNode)
    {
        node = new QSGGeometryNode;
        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), points);
        geometry->setLineWidth(1);
        geometry->setDrawingMode(GL_LINES);
        node->setGeometry(geometry);
        node->setFlag(QSGNode::OwnsGeometry);
        material = new QSGFlatColorMaterial;
        material->setColor("white");
        node->setMaterial(material);
        node->setFlag(QSGNode::OwnsMaterial);
    }
    else
    {
        node = static_cast<QSGGeometryNode *>(oldNode);
        geometry = node->geometry();
        geometry->allocate(points);
    }

    vertices = geometry->vertexDataAsPoint2D();
    lineHeight = (height() / 4);

    xs = 0;
    xe = width() - xs;

    for(int i = 0; i < 2; i++)
    {
        ys = ( i * lineHeight);
        vertices[(2*i)].set(xs, ys);
        vertices[(2*i)+1].set(xs + xe, ys);
    }

    node->markDirty(QSGNode::DirtyForceUpdate);
    return node;
}

line.h

#include <QQuickItem>

class Lines : public QQuickItem
{
    Q_OBJECT
public:
    Lines(QQuickItem *parent = 0);
    ~Lines();

    QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
};

的main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "line.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    qmlRegisterType<Lines>("lines", 1, 0, "Lines");

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

main.qml

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.0
import lines 1.0

Window {
    id: canvas

    height: 500
    width: 500
    color: "black"
    visible: true

    Rectangle {
        id: topBar

        height: 40
        Row {
            spacing: 10
            Button {
                text: "Small"
                onClicked: {
                    rect.visible = true
                    rect.width = 50
                }
            }
            Button {
                text: "Big"
                onClicked: {
                    rect.visible = true
                    rect.width = 100
                }
            }
            Button {
                text: "None"
                onClicked: {
                    rect.visible = false
                    rect.width = 0
                }
            }
        }
    }

    Rectangle {
        id: rect

        anchors {
            left: parent.left
            top: topBar.bottom
            bottom: parent.bottom
        }

        color: "grey"
        visible: false
    }

    Rectangle {
        id: rect2

        anchors {
            left: rect.right
            right: parent.right
            top: topBar.bottom
            bottom: parent.bottom
        }

        color: "black"

        Lines {
            id: lines

            x: 0
            y: 100

            width: parent.width
            height: 225
        }
    }
}

我看到当我选择左灰色块(使用按钮)时,线条没有正确重绘,我看到一些毛刺。下面的图片显示了带毛刺的输出。

Output of the Code

我尝试过调用node->markDirty(QSGNode::DirtyForceUpdate),但没有用。

如何解决此问题。请帮忙。提前谢谢。

0 个答案:

没有答案