Gtk and Cairo Working?

I’ve been having difficulty getting basic drawing going with Cairo and Gtk. The examples don’t seem to be working due to a type issue with what Gtk returns as a context and what Cairo expects.

using Gtk, Graphics
c = GtkCanvas()
win = GtkWindow(c, "Canvas")
ctx = getgc(c)
h = height(c)
w = width(c)
rectangle(ctx, 0, 0, w, h/2)
show(c)

generates error

ERROR: LoadError: MethodError: no method matching rectangle(::Gtk.GLib.FieldRef{GtkCanvas}, ::Int64, ::Int64, ::Int32, ::Float64)
Closest candidates are:
  rectangle(!Matched::Cairo.CairoContext, ::Real, ::Real, ::Real, ::Real) at /home/richardanaya/.julia/packages/Cairo/CXPG1/src/Cairo.jl:704
  rectangle(!Matched::GraphicsContext, ::Real, ::Real, ::Real, ::Real) at /home/richardanaya/.julia/packages/Graphics/XgkW4/src/Graphics.jl:452
Stacktrace:
 [1] top-level scope at none:0
 [2] include at ./boot.jl:326 [inlined]
 [3] include_relative(::Module, ::String) at ./loading.jl:1038
 [4] include(::Module, ::String) at ./sysimg.jl:29
 [5] exec_options(::Base.JLOptions) at ./client.jl:267
 [6] _start() at ./client.jl:436

afaics the getgc is already causing a problem as it doesn’t provide a CairoContext. I’d recommend to file an issue

Actually, it does, but you need to show(c) first to fully establish the widget. No need for an issue.

The example from http://juliagraphics.github.io/Gtk.jl/latest/manual/canvas.html works OK for me (Julia 1.1.0):

using Gtk, Graphics
c = @GtkCanvas()
win = GtkWindow(c, "Canvas")
@guarded draw(c) do widget
    ctx = getgc(c)
    h = height(c)
    w = width(c)
    # Paint red rectangle
    rectangle(ctx, 0, 0, w, h/2)
    set_source_rgb(ctx, 1, 0, 0)
    fill(ctx)
    # Paint blue rectangle
    rectangle(ctx, 0, 3h/4, w, h/4)
    set_source_rgb(ctx, 0, 0, 1)
    fill(ctx)
end
show(c)
1 Like

Hey, this is definitely a bug within Gtk. The issue is that the cairo context and surface are loaded lazily. There seems to be a reason for this (code is written by @tim.holy or @jameson). However, I have just pushed a fix for it:

https://github.com/JuliaGraphics/Gtk.jl/commit/15ed88c020e97c750cabad2dccbdf3a8a22b45af

So
] add Gtk#master

will solve it until we have made a new release.

It’s not obvious, but the code in draw(c) is executed after the show(c)

After ] add Gtk#master I still get the same error from the original posters code.

yep, something is wrong.

I have pushed something, which at least does not give an error, but it also does not draw. So the original code simply requires the redraw function (which solves the original issue since getgc is only called when the context is available)

Wierd, when I run that code nothing happens at all

windows or linux ?
which version of julia ?

Just a follow up, everything works now with new version!

Unfortunately I did not get the original code working (with Gtk#master) :

julia> ctx = getgc(c)
┌ Error: GtkCanvas not yet initialized.
└ @ Gtk ~/.julia/packages/Gtk/aP55V/src/cairo.jl:123

and a bit later

julia> rectangle(ctx, 0, 0, w, h/2)
ERROR: MethodError: no method matching rectangle(::Gtk.GLib.FieldRef{GtkCanvas}, ::Int64, ::Int64, ::Int32, ::Float64)

the original code is not supposed to work. Use the form outlined in http://juliagraphics.github.io/Gtk.jl/latest/manual/canvas.html
i.e. the getgc should happen in the draw callback.

1 Like

Confirmed, thanks!