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. Cannot destroy C++ Object in QML

Cannot destroy C++ Object in QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
10 Posts 3 Posters 5.8k Views
  • 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.
  • _ Offline
    _ Offline
    _antipattern_
    wrote on 1 Aug 2016, 18:43 last edited by
    #1

    Hi,

    in my code I want to delete an object that I pass to QtQuick in order to prevent a memory leak. However, I fail to be able to call 'deleteLater' from QML. It does not get exposed as a slot and when I create my own slot that destroys the object I get the error message "Invalid attempt to destroy() an indestructible object". Is there a way I can fix this?

    1 Reply Last reply
    0
    • J Online
      J Online
      jeremy_k
      wrote on 1 Aug 2016, 21:22 last edited by
      #2

      How was the object created?
      It may be easier to use QQmlEngine::setObjectOwnership() to assign the object to the QML engine, and allow garbage collection to handle it.

      Asking a question about code? http://eel.is/iso-c++/testcase/

      1 Reply Last reply
      0
      • _ Offline
        _ Offline
        _antipattern_
        wrote on 2 Aug 2016, 12:01 last edited by
        #3

        Thanks for your reply!

        The object is created on the heap in C++. I'd prefer a solution that would not require to have it handled by JavaScript.
        My use-case is this: The object wraps a task. If it fails the user is prompted (by a QML MessageDialog) whether there should be a retry (using the same object) or whether it should be canceled. In case of canceling I need to destroy the object. Is it possible to transfer ownership on the QML-side?

        R 1 Reply Last reply 2 Aug 2016, 12:12
        0
        • _ _antipattern_
          2 Aug 2016, 12:01

          Thanks for your reply!

          The object is created on the heap in C++. I'd prefer a solution that would not require to have it handled by JavaScript.
          My use-case is this: The object wraps a task. If it fails the user is prompted (by a QML MessageDialog) whether there should be a retry (using the same object) or whether it should be canceled. In case of canceling I need to destroy the object. Is it possible to transfer ownership on the QML-side?

          R Offline
          R Offline
          raven-worx
          Moderators
          wrote on 2 Aug 2016, 12:12 last edited by
          #4

          @_antipattern_ said:

          I'd prefer a solution that would not require to have it handled by JavaScript.

          Is it possible to transfer ownership on the QML-side?

          before that you have to decide what you want.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • _ Offline
            _ Offline
            _antipattern_
            wrote on 2 Aug 2016, 15:32 last edited by
            #5

            I'd like a way to prevent a memory leak. If possible I'd be great to be able to call the descructor, if not transfering the resposnibility to the GC is also fine.

            R 1 Reply Last reply 2 Aug 2016, 17:51
            0
            • _ _antipattern_
              2 Aug 2016, 15:32

              I'd like a way to prevent a memory leak. If possible I'd be great to be able to call the descructor, if not transfering the resposnibility to the GC is also fine.

              R Offline
              R Offline
              raven-worx
              Moderators
              wrote on 2 Aug 2016, 17:51 last edited by
              #6

              @_antipattern_
              than @jeremy_k gave you the solution already

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0
              • J Online
                J Online
                jeremy_k
                wrote on 2 Aug 2016, 22:16 last edited by
                #7

                Explicitly managing the lifetime of a C++ object used by QML is possible, but be aware that extra code is required on the QML side to detect invalid objects. Failure to do so can lead to javascript exceptions, application crashes, and the general variability of undefined behavior through the access of stray pointers.

                Things such as:

                property int prop: object.value
                

                become

                property int prop: isValid(object) ? object.value : -1
                

                Asking a question about code? http://eel.is/iso-c++/testcase/

                1 Reply Last reply
                0
                • _ Offline
                  _ Offline
                  _antipattern_
                  wrote on 3 Aug 2016, 12:01 last edited by
                  #8

                  I have trouble with both solutions. In the documentation I only found how to change the ownership of an object from C++ and not from JavaScript. Is this the only way?

                  Also, I didn't manage to explicitly manage the object's life-cycle, does the ownership need to be transfered first? I tried using the JavaScript delete.

                  J 1 Reply Last reply 3 Aug 2016, 22:04
                  0
                  • _ _antipattern_
                    3 Aug 2016, 12:01

                    I have trouble with both solutions. In the documentation I only found how to change the ownership of an object from C++ and not from JavaScript. Is this the only way?

                    Also, I didn't manage to explicitly manage the object's life-cycle, does the ownership need to be transfered first? I tried using the JavaScript delete.

                    J Online
                    J Online
                    jeremy_k
                    wrote on 3 Aug 2016, 22:04 last edited by
                    #9

                    There isn't an API to explicitly change the ownership from javascript.

                    The documentation briefly covers the topic at http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership.

                    Is the code sufficiently brief to post here?

                    Asking a question about code? http://eel.is/iso-c++/testcase/

                    1 Reply Last reply
                    0
                    • _ Offline
                      _ Offline
                      _antipattern_
                      wrote on 4 Aug 2016, 11:16 last edited by _antipattern_ 8 Apr 2016, 11:16
                      #10

                      Here are the important bits of my code:
                      main.qml

                      // ...
                      EntryModel {
                      	id: entryModel
                      	onError: {
                      		jobFailedDialog.informativeText = errorMessage
                      		jobFailedDialog.accepted.disconnect(failedJob.retry) // workaround for missing Qt::UniqueConnection in QML
                      		jobFailedDialog.accepted.connect(failedJob.retry)
                      		jobFailedDialog.rejected.disconnect(failedJob.deleteLater)
                      		jobFailedDialog.rejected.connect(failedJob.deleteLater)
                      		jobFailedDialog.open()
                      	}
                      }
                      
                      MessageDialog {
                      	id: jobFailedDialog
                              // ...
                      	standardButtons: StandardButton.Retry | StandardButton.Cancel
                      }
                      

                      EntryModel:

                      class EntryModel : public QAbstractListModel
                      {
                          // ...
                      signals:
                          void error(Job *failedJob, QString errorMessage);
                      
                      public slots:
                          void gatewayError(std::string error_string) {
                              qWarning() << "Error: " << QString::fromStdString(error_string);
                              emit error(static_cast<Job*>(QObject::sender()), QString::fromStdString(error_string));
                          }
                          // ...
                      };
                      

                      Job:

                      class Job : public QObject
                      {
                           // ...
                      
                      signals:
                          void error(const std::string &error_string);
                      
                      public slots:
                          void retry() { if (executed_) { executed_ = false; execute(); } }
                          
                          // ...
                      };
                      

                      The jobs are executed from the EntryModel and their error-signal is connected to EntryModel::gatewayError. This signal triggers the jobFailedDialog.
                      I left out the irrelevant bits, I hope the code is sufficient to clarify my problem.

                      1 Reply Last reply
                      0

                      1/10

                      1 Aug 2016, 18:43

                      • Login

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