GtkReactive vs Gtk

Is there any direct benefit aside from cleanliness, by using GtkReactive.jl over Gtk.jl? I’m only using Signals to do the gui elements, the rest of my code does not use Reactive.

For example, I made some scripting tools to work with input files, I now want to display last made changes to a Gtk.TextView window. I implemented it so that I use a Signal to accept and accumulate print statements, but I could just as well use an IOBuffer and do the same thing, without using Reactive.Signals.

Is there anything I can do with GtkReactive that can’t be done using only Gtk?

no. GtkReactive just is a different API to achieve the same thing.

I find that you can connect the back and front ends in a much more “organic” way with GtkReactive than with just Gtk. But I can admit that there were times where it was just simpler to just use Gtk. Every application and its own needs.

@yakir12: Do you have some larger application (Open Source) where one can see how you use it?

Sheesh, nothing I’m proud of right now, and it’s kind of hard to see my point here, but here’s where I use GtkReactive a lot:
https://github.com/yakir12/BeetleWay.jl/blob/master/src/log/gui.jl

You have one but not open source, right?

yes, its pretty large and I am facing some general performance issue (with Julia not Gtk itself). I am thus very interested in discussing the scalability of Gtk.jl applications.

The largest I know of is my editor, I haven’t had too much performance issues (besides precompilation and starting time) but I don’t have much interaction between the widgets, it’s mainly “press a key => do something” type of things. That said the windows version doesn’t really work (because of Gtk.jl issues afaik).

I guess being able to statically compile our applications would be ideal, but that will probably require some rewrite of Gtk.jl and a lot of work (see Compiling and building binaries from your julia code - #47 by sdanisch).

Your editor is actually a really great place for me to get ideas / see how to do things, since largely what I’m looking for is exactly what you describe: type, enter => see…

You didn’t use reactive signals I believe, is this because the GtkReactive package wasn’t there yet? If so, would you use it if you were to start GtkIDE.jl today?

this is a major issue for me right now. I integrated several smaller components into a larger application and now I have up to two minutes startup time. I have the feeling that this may be some fundamental issue since working with GtkBuilder leads (by definition) to type unstable code. Most of the time is spend in signal_connect and I have no idea how I can fix that.

GtkReactive wasn’t around yes, but I’m also not familiar with reactive programming techniques, so I would probably still use the basic Gtk signals.

@tobias.knopp can’t you do something like that to shield the type instability?

w = GAccessor.object(form_builder,"DialogCreateFile")
init!(w)

function init!(w::Gtk.GtkDialogLeaf)
    signal_connect(...
end

I have not yet tried that since my application has quite some widgets and signal_connects. It thus is quite some effort to restructure things. The builder thing might not be the actual issue since I use a Dict for storing config parameters. Thus my widgets are grouped in a type unstable composite type (together with the Dict) and I pass this to all callbacks. I have not yet a plan how I can structure this better. Thats why I am asking if you have a better pattern.

To give you an idea here is the pattern I use:


type DataViewerWidget <: Gtk.GtkBox
  handle::Ptr{Gtk.GObject}
  builder
  ... # data Dicts, whatsoever
end

getindex(m::DataViewerWidget, w::AbstractString) = G_.object(m.builder, w)


function DataViewerWidget()

  uifile = joinpath(Pkg.dir("Packagename"),"src","UI","builder","dataviewer.xml")

  b = Builder(filename=uifile)
  mainBox = G_.object(b, "boxDataViewer")
  m = DataViewerWidget( mainBox.handle, b, ...)
  Gtk.gobject_move_ref(m, mainBox)

  signal_connect(onMySliderChanged, , "changed")

  signal_connect(m["mySlider"], "toggled") do widget
     onMySliderChanged(m)
  end
  ...

  return m
end

function onMySliderChanged(m:: DataViewerWidget)

... # do stuff

end

I have quite some flexibility, the code is IMHO quite readable, but on a large scale this is super slow to load.