How to save a figure with a button in GLMakie?

I have a figure made with GLMakie, I can add button, but I don’t know how to link an action – namely saving the figure – to the button.
I have this example:

using GLMakie
xs = range(0, 10, length = 30)
ys = 0.5 .* sin.(xs)
fig = Figure()
ax = Axis(fig[1,1], title = "Example", ylabel = "Y", xlabel = "X")
sc = scatter
lines!(ax, xs, ys, linewidth = 5, color =:midnightblue)
fig[2,1] = buttongrid = GridLayout(tellwidth = false)
buttons = buttongrid[1,1] = [
    Button(fig, label = "Save Figure", fontsize = 18)
]
on(buttons[1].clicks) do 
    save(string(now(), ".png"), fig)
end

but I get the error:

julia> Error in callback:
MethodError: no method matching (::var"#11#12")(::Int64)
The function `#11` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  (::var"#11#12")()
   @ Main ~/Documents/Model/testButton.jl:13

Stacktrace:
  [1] #invokelatest#2
    @ ./essentials.jl:1055 [inlined]
  [2] invokelatest
    @ ./essentials.jl:1052 [inlined]
  [3] notify
    @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
  [4] setindex!(observable::Observable, val::Any)
    @ Observables ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123
  [5] (::Makie.var"#2086#2097"{Button})(::MouseEvent)
    @ Makie ~/.julia/packages/Makie/Y3ABD/src/makielayout/blocks/button.jl:72
  [6] (::Makie.var"#1510#1511"{Makie.var"#2086#2097"{Button}})(event::MouseEvent)
    @ Makie ~/.julia/packages/Makie/Y3ABD/src/makielayout/mousestatemachine.jl:94
  [7] #invokelatest#2
    @ ./essentials.jl:1055 [inlined]
  [8] invokelatest
    @ ./essentials.jl:1052 [inlined]
  [9] notify
    @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
 [10] setindex!
    @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123 [inlined]
 [11] (::Makie.var"#1535#1537"{Scene, Base.RefValue{Bool}, Base.RefValue{Union{Nothing, Makie.Mouse.Button}}, Base.RefValue{Float64}, Base.RefValue{Float64}, Base.RefValue{Bool}, Base.RefValue{Point{2, Float64}}, Base.RefValue{Bool}, Base.RefValue{Union{Nothing, Makie.Mouse.Button}}, Base.RefValue{Bool}, Base.RefValue{Point{2, Float32}}, Base.RefValue{Point{2, Float64}}, Base.RefValue{Makie.Mouse.Action}, Observable{MouseEvent}, Float64, Module})(event::Makie.MouseButtonEvent)
    @ Makie ~/.julia/packages/Makie/Y3ABD/src/makielayout/mousestatemachine.jl:365
 [12] #invokelatest#2
    @ ./essentials.jl:1055 [inlined]
 [13] invokelatest
    @ ./essentials.jl:1052 [inlined]
 [14] notify
    @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:206 [inlined]
 [15] setindex!
    @ ~/.julia/packages/Observables/YdEbO/src/Observables.jl:123 [inlined]
 [16] (::GLMakie.var"#mousebuttons#170"{Observable{Makie.MouseButtonEvent}})(window::GLFW.Window, button::GLFW.MouseButton, action::GLFW.Action, mods::Int32)
    @ GLMakie ~/.julia/packages/GLMakie/TH3rf/src/events.jl:104
 [17] _MouseButtonCallbackWrapper(window::GLFW.Window, button::GLFW.MouseButton, action::GLFW.Action, mods::Int32)
    @ GLFW ~/.julia/packages/GLFW/wmoTL/src/callback.jl:43
 [18] PollEvents
    @ ~/.julia/packages/GLFW/wmoTL/src/glfw3.jl:702 [inlined]
 [19] pollevents(screen::GLMakie.Screen{GLFW.Window}, frame_state::Makie.TickState)
    @ GLMakie ~/.julia/packages/GLMakie/TH3rf/src/screen.jl:485
 [20] on_demand_renderloop(screen::GLMakie.Screen{GLFW.Window})
    @ GLMakie ~/.julia/packages/GLMakie/TH3rf/src/screen.jl:935
 [21] renderloop(screen::GLMakie.Screen{GLFW.Window})
    @ GLMakie ~/.julia/packages/GLMakie/TH3rf/src/screen.jl:963
 [22] (::GLMakie.var"#71#72"{GLMakie.Screen{GLFW.Window}})()
    @ GLMakie ~/.julia/packages/GLMakie/TH3rf/src/screen.jl:823
1 Like

You forgot to add an argument to the do closure, it’s the number of clicks. You don’t need it for your logic but the function has to take one argument or you get a method error

2 Likes

Thank you; I added click on on(buttons[1].clicks) do and now it works.

1 Like