Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [solved] Can't update custom component autoly
Forum Updated to NodeBB v4.3 + New Features

[solved] Can't update custom component autoly

Scheduled Pinned Locked Moved QML and Qt Quick
3 Posts 2 Posters 1.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Landy
    wrote on last edited by
    #1

    Hi all,

    I defined a custom component named "Circle" with C++.
    I can use it in QML project.
    But I found that the Circle can't be updated in the project.
    I mean, if I add a new Circle dynamically, the Circle which is added will not show until I switch windows.
    Here are my codes:

    Circle.h:
    @#ifndef CIRCLE_H
    #define CIRCLE_H

    #include <QDeclarativeItem>

    class Circle : public QDeclarativeItem
    {
    Q_OBJECT
    Q_PROPERTY(int radius READ radius WRITE setRadius)
    Q_PROPERTY(QColor color READ color WRITE setColor)
    public:
    explicit Circle(QDeclarativeItem *parent = 0);
    void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
    int radius() const;
    void setRadius(int);
    QColor color() const;
    void setColor(QColor);

    private:
    int m_radius;
    QColor m_color;
    };

    #endif // CIRCLE_H
    @

    Circle.cpp:
    @#include "circle.h"
    #include <QPainter>

    Circle::Circle(QDeclarativeItem *parent) :
    QDeclarativeItem(parent),
    m_radius(50), m_color(Qt::white)
    {
    setFlag(QGraphicsItem::ItemHasNoContents, false);
    }

    void Circle::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
    {
    int originX = m_radius;
    int originY = m_radius;
    QRadialGradient g(originX, originY, m_radius, originX, originY);
    g.setColorAt(0, m_color);
    g.setColorAt(1, m_color);
    p->save();
    p->setBrush(g);
    p->drawEllipse(QPoint(originX, originY), m_radius, m_radius);
    p->restore();
    qDebug() << "originX" << originX << "originY" << originY;
    qDebug() << "width" << p->device()->width() << "height" << p->device()->height();
    }

    int Circle::radius() const
    {
    return m_radius;
    }

    void Circle::setRadius(int _radius)
    {
    m_radius = _radius;
    }

    QColor Circle::color() const
    {
    return m_color;
    }

    void Circle::setColor(QColor _color)
    {
    m_color = _color;
    }
    @

    Circle.qml
    @import QtQuick 1.0
    import Circle 1.0

    Circle {
    id: root
    property bool isCurCircle: true

    signal correctClicked
    signal incorrectClicked
    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (isCurCircle) {
                isCurCircle = false;
                parent.parent.correctCircleClicked();
            } else {
                parent.parent.incorrectCircleClicked();
            }
        }
    }
    

    }
    @

    main.qml
    @import QtQuick 1.0
    import "./data.js" as Datas
    import Circle 1.0

    Rectangle {
    id: root
    width: 500
    height: 500
    color: "black"

    MouseArea {
        anchors.fill: parent
        onClicked: {
            addCircle();
        }
    }
    
    function addCircle() {
        var component = Qt.createComponent('Circle.qml');
        if (Component.Ready == component.status) {
            initCircle(component.createObject(root));
        }
    }
    
    function initCircle(_circle) {
        _circle.x = getRandom(10, 90) * 5;
        _circle.y = getRandom(10, 90) * 5;
        _circle.radius = getRandom(1, 10) * 5;
        var random = getRandom(0, 5);
        switch (getRandom(0, 5)) {
        case 0:
            _circle.color = "red";
            break;
        case 1:
            _circle.color = "yellow";
            break;
        case 2:
            _circle.color = "blue";
            break;
        case 3:
            _circle.color = "green";
            break;
        case 4:
            _circle.color = "white";
            break;
        case 5:
            _circle.color = "pink";
            break;
        }
    }
    
    function getRandom(_min, _max) {
        return Math.round(Math.random()*(_max-_min)+_min);
    }
    
    function correctCircleClicked() {
        console.log("correct Clicked");
        addCircle();
    }
    
    function incorrectCircleClicked() {
        console.log("incorrect Clicked");
        addCircle();
    }
    
    Component.onCompleted: {
        addCircle();
    }
    

    }
    @

    BTW, I can't use MouseArea in Circle. I don't know why.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mbrasser
      wrote on last edited by
      #2

      Hi,

      It doesn't look like your item is being given a geometry, which is probably what is causing the problems. Things to look at:

      • Have the setRadius function set the width/height of the item (using setImplicitWidth/setImplicitHeight)
      • You may also want to reimplement the virtual boundingRect function, if your paint area and size are not always identical.
      • You should generally call update() when your item needs to be redrawn (i.e. it would make sense to call it in your setter functions, as changing the radius or color should cause the item to be redrawn).

      Hope that helps.

      Regards,
      Michael

      1 Reply Last reply
      0
      • L Offline
        L Offline
        Landy
        wrote on last edited by
        #3

        Yes, you're right.
        Following your suggestions, the problem have been resolved.
        Width/height must be set in the component.
        Thanks, Michael.
        [quote author="mbrasser" date="1313368200"]Hi,

        It doesn't look like your item is being given a geometry, which is probably what is causing the problems. Things to look at:

        • Have the setRadius function set the width/height of the item (using setImplicitWidth/setImplicitHeight)
        • You may also want to reimplement the virtual boundingRect function, if your paint area and size are not always identical.
        • You should generally call update() when your item needs to be redrawn (i.e. it would make sense to call it in your setter functions, as changing the radius or color should cause the item to be redrawn).

        Hope that helps.

        Regards,
        Michael

        Regards,
        Michael[/quote]

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved