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. Segmentation fault when binding C++ function to QML property

Segmentation fault when binding C++ function to QML property

Scheduled Pinned Locked Moved Solved QML and Qt Quick
3 Posts 2 Posters 1.3k 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.
  • O Offline
    O Offline
    Obi-Wan
    wrote on 28 May 2020, 13:26 last edited by
    #1

    Hello!

    I have two C++ classes registered with QML that are instantiated in QML as components.
    I also have a third component that binds a C++ function to a property.

    These three components are instantiated in the order below:

    Component1 [
    	id: comp1
    }
    
    Component2 {
    	id: comp2
            comp1prop: comp1
    }
    
    Component3 {
    	property Component2 comp2prop: comp2
    	property int number : comp2prop.calcNumber()
    }
    

    Component 2 has a pointer to Component1 and has a set function that sets this pointer based on what the property is set to in QML.

    class Component2 : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(Component1* comp1prop READ comp1prop WRITE setComp1prop NOTIFY comp1PropChanged)
    
        int calcNumber() { return comp1prop_->aNumber() }
    
    ...
    private:
        Component1* comp1prop_ = nullptr;
    

    This works fine whenever i explicitly call calcNumber() at some point, but not when it is used in a property binding.
    The program then crashes due to a segmentation fault.

    The answer seems to be that Component2's pointer to Component1 is not yet set, but in my mind this should work because Component 2 is created after Component 1 and I assumed the property, and thus the pointer, would be set then. So when component 3 uses the function in component 2, everhything should already exist.

    What am I missing?
    Is this bad practice? What exactly is bad practice in that case?

    (Just to add: I very recently started working with QML after a long time away from it so everything is a bit hazy ...!)

    J 1 Reply Last reply 28 May 2020, 13:33
    0
    • O Obi-Wan
      28 May 2020, 13:26

      Hello!

      I have two C++ classes registered with QML that are instantiated in QML as components.
      I also have a third component that binds a C++ function to a property.

      These three components are instantiated in the order below:

      Component1 [
      	id: comp1
      }
      
      Component2 {
      	id: comp2
              comp1prop: comp1
      }
      
      Component3 {
      	property Component2 comp2prop: comp2
      	property int number : comp2prop.calcNumber()
      }
      

      Component 2 has a pointer to Component1 and has a set function that sets this pointer based on what the property is set to in QML.

      class Component2 : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(Component1* comp1prop READ comp1prop WRITE setComp1prop NOTIFY comp1PropChanged)
      
          int calcNumber() { return comp1prop_->aNumber() }
      
      ...
      private:
          Component1* comp1prop_ = nullptr;
      

      This works fine whenever i explicitly call calcNumber() at some point, but not when it is used in a property binding.
      The program then crashes due to a segmentation fault.

      The answer seems to be that Component2's pointer to Component1 is not yet set, but in my mind this should work because Component 2 is created after Component 1 and I assumed the property, and thus the pointer, would be set then. So when component 3 uses the function in component 2, everhything should already exist.

      What am I missing?
      Is this bad practice? What exactly is bad practice in that case?

      (Just to add: I very recently started working with QML after a long time away from it so everything is a bit hazy ...!)

      J Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 28 May 2020, 13:33 last edited by
      #2

      @Obi-Wan
      Hi, I think the property bindings are evaluated before the component is completed, so your comp1_prop_ is still a nullptr. And I don't think anything in QML guarantees order of initialization, but I'm happy to be contradicted by someone on this.

      this should work:

      int calcNumber() { return comp1prop_  ? comp1prop_->aNumber() : 0 }
      

      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      O 1 Reply Last reply 30 May 2020, 14:57
      1
      • J J.Hilk
        28 May 2020, 13:33

        @Obi-Wan
        Hi, I think the property bindings are evaluated before the component is completed, so your comp1_prop_ is still a nullptr. And I don't think anything in QML guarantees order of initialization, but I'm happy to be contradicted by someone on this.

        this should work:

        int calcNumber() { return comp1prop_  ? comp1prop_->aNumber() : 0 }
        
        O Offline
        O Offline
        Obi-Wan
        wrote on 30 May 2020, 14:57 last edited by
        #3

        @J-Hilk said in Segmentation fault when binding C++ function to QML property:

        Hi, I think the property bindings are evaluated before the component is completed, so your comp1_prop_ is still a nullptr.

        ...

        int calcNumber() { return comp1prop_  ? comp1prop_->aNumber() : 0 }
        

        This seems to be the case, and checking the pointer in C++ first does fix the issue. What also seems to work is doing this in Component3:

        Component.onCompleted: {
                number = Qt.binding(function() {return comp2prop.calcNumber()})
        }
        

        But I'm not sure this is a safe thing to do, specifically because of what you mention:

        And I don't think anything in QML guarantees order of initialization, but I'm happy to be contradicted by someone on this.

        The only thing I can find in the documentation about this is that the order of the onCompleted handlers is undefined, but I struggle to understand the full consequence of this. I think, in coming from pure C++ to QML and C++, I struggle to wrap my head around the structure and order of the code, and the relation between C++ objects that are created in QML as Components. I'm just thinking loudly now, and this is not the place to "figure it all out", but if you have any suggestions I'm all ears.

        1 Reply Last reply
        0

        1/3

        28 May 2020, 13:26

        • Login

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