0

The presented code does the following:

<1> Create object of QObject derived class and expose it to QML

<2> The class has a pointer to another QObject derived class and the pointer is accessible to QML via Q_PROPERTY.

<3> MouseArea in QML detects user-click and simply asks the c++ code for the pointer to be deleted.

<4> Color of rectangle turns black once this is detected.

The problem is that while certain approaches detect the deletion of the pointer by c++ other approaches don't.

Look at the inline comments:

Combination of (1) and (1b) works

Combination of (1) and (1d) does not work

(2) alone by itself works but (3) alone by itself does not.

When things work you should see the color of the Rectangle turn to black from yellow.

Can someone please explain this behaviour?

CPP codes:

class Name : public QObject
{
   Q_OBJECT
   Q_PROPERTY(bool boolVal READ boolVal CONSTANT FINAL)
public:
   bool boolVal() const {return true;}
};

class Root : public QObject
{
   Q_OBJECT
   Q_PROPERTY(QObject* name READ name CONSTANT FINAL)
public:
   QObject* name() const {return m_pName;}
   Q_INVOKABLE void deleteName() {delete m_pName; m_pName = 0;}
private:
   Name *m_pName {new Name};
};

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

    Root objRoot;
    QtQuick2ApplicationViewer viewer0;
    viewer0.rootContext()->setContextProperty("objRoot", &objRoot);
    viewer0.setMainQmlFile(QStringLiteral("qml/dualWindowApp/main.qml"));
    viewer0.showExpanded();

    return app.exec();
}

QML Code:

import QtQuick 2.0

Rectangle {
    width: 360
    height: 360

    color: "red"

    Rectangle {
       id: objRect
       anchors {left: parent.left; top: parent.top}
       height: 70; width: 70;

       property bool checked
       property QtObject temp: objRoot.name

       color: checked ? "yellow" : "black"                                 //                        (1)

       //color: objRect.temp && objRect.temp.boolVal ? "yellow" : "black"  //--->WORKS               (2)
       //color: objRoot.name && objRoot.name.boolVal ? "yellow" : "black"  //--->DOES NOT WORK !!!   (3)

       Binding on checked {
          //value: objRect.temp && objRect.temp.boolVal                    //--->DOES NOT WORK !!!   (1a)
          //value: objRect.temp !== null && objRect.temp.boolVal           //--->WORKS               (1b)
          value: objRect.temp ? objRect.temp.boolVal : false               //--->WORKS               (1c)

          //Using directly without collecting in local QtQobject temp:
          //----------------------------------------------------------
          //value: objRoot.name && objRoot.name.boolVal                    //--->DOES NOT WORK !!!   (1d)
          //value: objRoot.name !== null && objRoot.name.boolVal           //--->DOES NOT WORK !!!   (1e)
          //value: objRoot.name ? objRoot.name.boolVal : false             //--->DOES NOT WORK !!!   (1f)
       }

       Text {
           text: "Destroy"
           anchors.centerIn: parent
       }

       MouseArea {
           anchors.fill: parent
           onClicked: objRoot.deleteName()
       }
    }
}

using: {Qt/QML 5.2.0, Win 7, MinGW 4.8, QtQuick 2.0}

ustulation
  • 3,600
  • 25
  • 50

1 Answers1

0

Your property declaration looks strange to me: name can obviously change, but you've declared it CONSTANT. My guess is it it'd work a whole lot better without the CONSTANT, and instead provide a NOTIFY of a nameChanged signal emitted when the value of name changes, else there's no guarantee the QML states bound to the C++ properties will be updated.

timday
  • 24,582
  • 12
  • 83
  • 135
  • I understand what you say. That is what i do normally. But for the QObject* i think QML somehow understands the c++ object being destroyed. Even if you don't explicitly allocate a nullptr to the c++ member pointer `m_pName` after its deletion, the codes that work will still get a notification that the bound QtObject is null. <1> How does that happen? <2> And even if you were to have a notifier, when would you emit it? The pointer itself does not change, only the pointee is deleted and that can happen via so many different mechanisms (eg., silently via Qt's parent child memory management etc) – ustulation Jun 28 '14 at 14:14