Page 1 of 2

[SOLVED] gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Thu Oct 10, 2013 8:38 pm
by tleedavidson
Hi All,

Now that I've decided to go ahead and sink my teeth into Cobra, I am trying to adapt the how-to '390-GTK.cobra' (referenced below) to use gtk-sharp3 (GTK+3) and GtkBuilder with a dynamically loaded XML GUI definition. (The XML file was created with Glade 3.14.2 so 'libglade' not required, but I have not included the content of the file here because Gtk::Builder::addFromFile() does not complain. I can though, if needed.)

References:
http://cobra-language.com/how-to/GTK/ ('390-GTK.cobra')
http://docs.go-mono.com/?link=M%3aGtk.B ... ectSignals
https://developer.gnome.org/gtk3/stable ... ct-signals

Here's what I'm using:
Code: Select all
# cobra --version
# Cobra 0.9.4 on Mono 2.10.9 CLR v4.0.30319 on Mageia 3


Here's the program code ('gtksharp.cobra'):
@args 3.0gtk-sharp-3.0

use Gtk

class ToggleButtons

def main
ToggleButtons().run

def onDeleteEvent(obj, args as DeleteEventArgs)
Application.quit

def onExitButtonEvent(obj, args as EventArgs)
Application.quit

def run
Application.init

gui = Gtk.Builder()
gui.addFromFile('togglebuttons.xml')
gui.connectSignals()

Application.run
(I'm not sure why the [cobra] tag is mangling the "@args" line. It should be, "@args -pkg:gtk-sharp-3.0")

And this is what I get when I try to run it:
Code: Select all
# cobra -d gtksharp.cobra
# gtksharp.cobra(41): error: Cannot find a definition for "connectSignals" in "gui" whose type is "Builder".
# Compilation failed - 1 error, 0 warnings
# Not running due to errors above.


I've noticed that the gtk-sharp method names are in UpperCamelCase (PascalCase?), but Cobra uses lowerCamelCase even for imported libraries. The friendly compiler clued me in to this when I tried gui.AddFromFile:
Code: Select all
# gtksharp.cobra(40): error: Cannot find a definition for "AddFromFile" in "gui" whose type is "Builder". There is a member named ".addFromFile" with a similar name.


Unfortunately, it isn't giving me any hints for gui.connect.Signals.

Is this a bug, or am I just simply missing something brain-dead-stupid?

Thanks for any help.

T. Lee

Re: gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Fri Oct 11, 2013 10:52 am
by Charles
I haven't used gtk 3 yet, but here are some things to help you progress:

-- Yes, methods in Cobra are referenced as .fooBar. This is not going to be the source of your problem as this has been in place for a long time. As you discovered, if the case isn't quite right, Cobra will be informative.

-- You can use -v to see what libs Cobra is loading including their paths:
Code: Select all
cobra -v hello.cobra
...
Phase: Reading libraries
Reading assembly:  mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
              at:  /Library/Frameworks/Mono.framework/Versions/3.2.3/lib/mono/4.5/mscorlib.dll
Reading assembly:  System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
              at:  /Library/Frameworks/Mono.framework/Versions/3.2.3/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll
Loading reference: Cobra.Core.dll
Reading assembly:  Cobra.Core, Version=0.0.3046.1, Culture=neutral, PublicKeyToken=null
              at:  /Users/chuck/Dropbox/Projects/Cobra/workspace-u/Source/Cobra.Core.dll
Loading reference: System.Core.dll
Reading assembly:  System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
              at:  /Library/Frameworks/Mono.framework/Versions/3.2.3/lib/mono/gac/System.Core/4.0.0.0__b77a5c561934e089/System.Core.dll
...


-- You can use the @help directive to see the interface of a class in Cobra terms. For example:
# change this:
gui.addFromFile('togglebuttons.xml')
# to this:
@help gui.addFromFile('togglebuttons.xml')

... and compile again. @help will cause the Cobra compiler to generate a .html file which will automatically be opened.

Re: gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Sat Oct 12, 2013 7:50 am
by tleedavidson
Well, I am really confused now.

cobra -v shows that Cobra is loading cairo-sharp.dll, pango-sharp.dll, atk-sharp.dll, gdk-sharp.dll, gtk-sharp.dll, glib-sharp.dll, and gio-sharp.dll; all from /lib/mono/gtk-sharp-3.0/.

But the html help page generated by @help gui.addFromFile('togglebuttons.xml') lists a Gtk::Builder method (autoconnect) that, according to the Mono Documentation, is a method of the glade-sharp library (Namespace: Glade) in its XML class; ie. a Glade::XML method. @help is quite a slick feature, by the way.

So, I am at a loss as to how to progress. This apparent mixing of methods from different namespaces and classes confuses me to no end, and I will likely not spend any more time on this. But, thank you very much for trying to help.

Best regards,
T. Lee

Re: gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Sat Oct 12, 2013 12:08 pm
by Charles
Glad you liked @help! I don't hear much about it. I don't think it gets used much.

Sorry gtk3 didn't go well for you. I have used gtk2.x plenty though so if you end up using that, I might have more information for you.

Re: gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Mon Oct 14, 2013 5:02 am
by hopscc
Those doc refs ( For what they are worth) say connectSignals takes an arg.
Code: Select all
public void ConnectSignals (BuilderConnectFunc func)

Your code is calling it without one so I think the error message is indicating it cant find a match for a call to a no-arg .connectSignals
given what is available in the library.

i.e
You need to call (the cobra defn) equivalent of
def connectSignals(func as BuilderConnectFunc)
.

Try getting a BuilderConnectFunc object,( however you do that ( I dont use mono/GTK) - presumably its a table of names and fn refs)
and calling it with that as an arg.
bcf  = .... # find, make or ref a BuilderConnectFunc Object
gui.connectSignals(bcf)

Re: gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Mon Oct 14, 2013 6:13 am
by hopscc
Theres a couple of variants of connectSignals (in the C libs at least)- the one you referenced and I mentioned above looks like a custom override version, theres another that just specifies optional userData and most examples I saw in google skimming just pass null here
relying on the signal name and function name (string) reference both being specified in the glade file and some sort of runtime dynamic symbol lookup to resolve the function name to code.

try
gui.connectSignals(nil)


Looks like there are additional constraints with your supplied signal handler methods being publicly accessible and specially marked (on Windows) or correctly specified to dynamically link ( on (lin)unices) but you havent got to them yet :)

Re: gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Mon Oct 14, 2013 6:39 am
by hopscc
Wait, theres more.

This StackOverflow csharp gtk builder example
seems to indicate should use

gui.autoConnect

rather than gui.connectSignals

# untested 
# whatever need for pkg ref here

use Gtk

class ToggleButtons

def main
ToggleButtons().run

def onDeleteEvent(obj, args as DeleteEventArgs) is shared
Application.quit

def onExitButtonEvent(obj, args as EventArgs) is shared
Application.quit

def run
Application.init

gui = Gtk.Builder()
gui.addFromFile('togglebuttons.xml')
gui.autoConnect(this)

Application.run


which makes sense for what you are seeing if for gtk3 connectSignals is moved to a different level of the API and replaced with .autoConnect.

Re: gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Sun Oct 20, 2013 2:43 pm
by tleedavidson
Thank you, hopscc. Sorry for the late response, but somehow I guess I wasn't subscribed to my own thread :roll:

The top-rated answer at that StackOverflow topic is actually mine. I posted that after figuring out how to use GTK+3 with C#. And, yes, you are correct. The method to use is autoconnect.

I have also got it working with Boo. But Cobra will not connect the handlers saying it cannot find them. I had previously tried with my own version of the suggested code you posted. And now, for the sake of being on the same page, I have taken your code, corrected it for a necessary package and proper case, and have tried to execute:
@args 3.0gtk-sharp-3.0

use Gtk

class ToggleButtons

def main
ToggleButtons().run

def onDeleteEvent(obj, args as DeleteEventArgs) is shared
Application.quit

def onExitButtonEvent(obj, args as EventArgs) is shared
Application.quit

def run
Application.init

gui = Gtk.Builder()
gui.addFromFile('togglebuttons.xml')
gui.autoconnect(this)

Application.run

(The [cobra] tag mangles the necessary package: "@args -pkg:gtk-sharp-3.0")

The result, in short, was:
Code: Select all
# No handler onDeleteEvent found for signal delete-event


I can't help but wonder if this is because "self" methods in Cobra need to be prepended with a dot. I tried prepending a dot to the handler names in the XML file, but that didn't work either.

Re: gtk-sharp3, GtkBuilder, ConnectSignals not found

PostPosted: Sun Oct 20, 2013 4:00 pm
by Charles
In order to vend out "normal" .NET method and property names to other language users (particularly C# and VB) who may consume libraries written in Cobra, the Cobra compiler will cap them in the generated code. So "onDeleteEvent" becomes "OnDeleteEvent".

Does your glade file need to say "OnDeleteEvent"? Does that help?

[SOLVED] Re: gtk-sharp3, GtkBuilder, ConnectSignals not foun

PostPosted: Sun Oct 20, 2013 7:36 pm
by tleedavidson
Yes, Charles, that absolutely does help. It works now!

So, for future reference for anyone who is interested, here is the code and the supporting XML file that defines the GUI objects.


The Doc comment for the beginning of the code file:
"""
A small example of using the GTK+3 (gtk-sharp) GUI library.

How to compile:
cobra -c -pkg:gtk-sharp-3.0 togglebuttons.cobra

URLs of interest:
http://www.mono-project.com/GtkSharp
http://www.mono-project.com/GtkSharp:_Hello_World
http://www.mono-project.com/GtkSharpBeginnersGuide
http://docs.go-mono.com/?link=T%3aGtk.Builder

Credit:
Adapted from http://cobra-language.com/how-to/GTK/
"""

@args 3.0gtk-sharp-3.0

use Gtk

class ToggleButtons

def main
ToggleButtons().run

def onDeleteEvent(obj, args as DeleteEventArgs) is shared
Application.quit

def onExitButtonEvent(obj, args as EventArgs) is shared
Application.quit

def run
Application.init

gui = Gtk.Builder()
gui.addFromFile('togglebuttons.xml')
gui.autoconnect(this)

Application.run

(Be sure the '@args' line says "@args -pkg:gtk-sharp-3.0")

togglebuttons.xml:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <!-- interface-requires gtk+ 3.0 -->
  <object class="GtkWindow" id="window">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">Toggle Buttons</property>
    <signal name="delete-event" handler="OnDeleteEvent" swapped="no"/>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkToggleButton" id="togglebutton1">
            <property name="label" translatable="yes">Button 1</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="halign">center</property>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">False</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkToggleButton" id="togglebutton2">
            <property name="label" translatable="yes">Button 2</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="halign">center</property>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">False</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkSeparator" id="separator1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="button1">
            <property name="label" translatable="yes">Close</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="halign">center</property>
            <signal name="clicked" handler="OnExitButtonEvent" swapped="no"/>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">False</property>
            <property name="position">3</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
(Be sure the the event handler names are PascalCase, not camelCase, in this GUI file.)

Enjoy!

T. Lee