Skip to content

Segfault when exiting Julia after replacing a JuliaItemModel #218

Description

@tetrakai1

Hi,

My Qt app runs fine, but then after closing it there is segfault when exiting the Julia session.

As discussed here

MWE 1:

using QML

# const qml_file = joinpath(pwd(), "code", "qml", "test.qml")

function update_props()
    props["fruits"] = fruits2
end

function main(qml_file, props)
    loadqml(qml_file, props = props)
    exec()
end

mutable struct Fruit
    name::String
    cost::Float64
end

fruits  = JuliaItemModel([Fruit("apple", 1.0), Fruit("orange", 2.0)])
fruits2 = JuliaItemModel([Fruit("banana", 1.0), Fruit("pear", 2.0)])

props = JuliaPropertyMap("fruits" => fruits)

@qmlfunction update_props

# main(qml_file, props)


mktempdir() do folder
            path = joinpath(folder, "test.qml")
            write(path, """
                  import QtQuick
                  import QtQuick.Controls
                  import QtQuick.Layouts
                  import org.julialang

                  ApplicationWindow {
                      id: mainWin
                      title: "My Application"
                      width: 400
                      height: 400
                      visible: true
                    
                      ColumnLayout{
                        anchors.fill: parent
                    
                          Button {
                              height: 200
                              Layout.fillWidth: true
                              text: "Update Fruit"
                              onClicked: { 
                                  Julia.update_props()
                                  console.log("Value:", props.fruits) 
                              }
                         }
                          ListView {
                              model: props.fruits
                              Layout.fillHeight: true
                              Layout.fillWidth: true
                              delegate: Row {
                                  Text {
                                      text: name
                                  }
                              }
                          }
                      }
                  }
                  """)
            main(path, props)
          end

MWE 2:

using QML

# const qml_file = joinpath(pwd(), "code", "qml", "test.qml")

function update_props()
    props["fruits"] = fruits2
end

function main(qml_file, props)
    loadqml(qml_file, props = props)
    exec()
end

mutable struct Fruit
    name::String
    cost::Float64
end

fruits  = JuliaItemModel([Fruit("apple", 1.0), Fruit("orange", 2.0)])
fruits2 = JuliaItemModel([Fruit("banana", 1.0), Fruit("pear", 2.0)])

props = JuliaPropertyMap("fruits" => fruits)

@qmlfunction update_props

# main(qml_file, props)


mktempdir() do folder
            path = joinpath(folder, "test.qml")
            write(path, """
                  import QtQuick
                  import QtQuick.Controls
                  import QtQuick.Layouts
                  import org.julialang

                  ApplicationWindow {
                      id: mainWin
                      title: "My Application"
                      width: 400
                      height: 400
                      visible: true

                      Connections {
                        target: button
                        // onClicked: Julia.update_props()
                        function onClicked() { Julia.update_props() }
                      }
                    
                      ColumnLayout{
                        anchors.fill: parent
                    
                          Button {
                              id: button
                              height: 200
                              Layout.fillWidth: true
                              text: "Update Fruit"
                              // onClicked: { 
                              //     Julia.update_props()
                              //     console.log("Value:", props.fruits) 
                              // }
                         }
                          ListView {
                              model: props.fruits
                              Layout.fillHeight: true
                              Layout.fillWidth: true
                              delegate: Row {
                                  Text {
                                      text: name
                                  }
                              }
                          }
                      }
                  }
                  """)
            main(path, props)
          end

It isn't clear whether this is misusing the package or a bug.

Thanks.

Activity

  1. ufechner7 commented on May 6, 2025

    @ufechner7
    Member

    For completeness:

    julia> versioninfo()
    Julia Version 1.11.5
    Commit 760b2e5b739 (2025-04-14 06:53 UTC)
    Build Info:
      Official https://julialang.org/ release
    Platform Info:
      OS: Linux (x86_64-linux-gnu)
      CPU: 4 × Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz
      WORD_SIZE: 64
      LLVM: libLLVM-16.0.6 (ORCJIT, skylake)
    Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores)
    
    julia> Pkg.status()
      [336ed68f] CSV v0.10.15
      [1f15a43c] CxxWrap v0.16.2
      [3b531cbf] DataConvenience v0.3.6
      [a93c6f00] DataFrames v1.7.0
      [c601a237] Interact v0.10.5
      [510215fc] Observables v0.5.5
      [d96e819e] Parameters v0.12.3
      [2db162a6] QML v0.9.2
      [2913bbd2] StatsBase v0.34.4
      [f3b207a7] StatsPlots v0.15.7
    

    I can reproduce the issue.

  2. tetrakai1 commented on May 7, 2025

    @tetrakai1
    Author

    This is a crosspost of my workaround from the discourse thread.

    This works. First clear the array in QML, then push to it from Julia:

    using QML
    
    # const qml_file = joinpath(pwd(), "code", "qml", "test.qml")
    
    function update_props()
        props["fruits"] = fruits2
    end
    
    # First clear props in QML
    function update_props()
        [push!(props["fruits"], fruits2[i]) for i in 1:length(fruits2)]
    end
    
    
    function main(qml_file, props)
        loadqml(qml_file, props = props)
        exec()
    end
    
    mutable struct Fruit
        name::String
        cost::Float64
    end
    
    fruits  = JuliaItemModel([Fruit("apple", 1.0), Fruit("orange", 2.0)])
    fruits2 = JuliaItemModel([Fruit("banana", 1.0), Fruit("pear", 2.0)])
    
    props = JuliaPropertyMap("fruits" => fruits)
    
    @qmlfunction update_props
    
    # main(qml_file, props)
    
    
    mktempdir() do folder
                path = joinpath(folder, "test.qml")
                write(path, """
                      import QtQuick
                      import QtQuick.Controls
                      import QtQuick.Layouts
                      import org.julialang
    
                      ApplicationWindow {
                          id: mainWin
                          title: "My Application"
                          width: 400
                          height: 400
                          visible: true
                        
                          ColumnLayout{
                            anchors.fill: parent
                        
                              Button {
                                  height: 200
                                  Layout.fillWidth: true
                                  text: "Update Fruit"
                                  onClicked: {
                                      // First clear then update from julia
                                      props.fruits.clear() 
                                      Julia.update_props()
                                  }
                             }
                              ListView {
                                  model: props.fruits
                                  Layout.fillHeight: true
                                  Layout.fillWidth: true
                                  delegate: Row {
                                      Text {
                                          text: name
                                      }
                                  }
                              }
                          }
                      }
                      """)
                main(path, props)
              end

    Still there should be a warning instead of that segfault.

  3. barche commented on May 8, 2025

    @barche
    Collaborator

    I confirm that I can reproduce this, it's probably a bug related to not disconnecting notification functions when changing the property, so it's a QML.jl bug, not wrong usage :)

  4. barche commented on Jun 24, 2026

    @barche
    Collaborator

    Fixed in QML.jl v0.13.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions