Ruby-Gtk question

Hi,

Is there an equivalent to the g_signal_connect_swapped() gtk+ call
in Ruby. Following is the c code that allows a button to destroy
an including window:

±-----------------------------------------------------------+
| g_signal_connect_swapped (G_OBJECT (button), “clicked”, |

| G_CALLBACK (gtk_widget_destroy), |

| (gpointer) window); |
±-----------------------------------------------------------+

The following seems to be the Ruby way to do the above:

±----------------------------------------------------+
| button = Gtk::Button.new("_Hello World") |
| button.signal_connect(“clicked”) { Gtk.main_quit } |
±----------------------------------------------------+

However, it is sometimes necessary to destroy a certain widget,
and I believe it should be made available to the callback in
some other way than via a global variable! Which brings me back
to my original question.

Hi,

In [email protected]
“[ruby-gnome2-devel-en] Ruby-Gtk question” on Wed, 31 Dec 2008
21:42:15 +0100,
Torli B. [email protected] wrote:

±-----------------------------------------------------------+
some other way than via a global variable! Which brings me back
to my original question.

You don’t need to use a global variable. Signal handlers are
closure.

window = get_window
button = Gtk::Button.new(“_Hello World”)
button.signal_connect(“clicked”) {window.destroy}

Happy new year,

kou

Kouhei S. wrote:

You don’t need to use a global variable. Signal handlers are
closure.

Of course, Kou. Now that you’ve mentioned it I do feel a bit silly.
My mind has not yet switched back to Ruby, and perhaps I’m trying
too hard to see relationships to the good old GTK+ foundation.

Thank you, and happy New Year to you too!
Torli

Cursor is a {{ Gdk::Window }} feature. Gtk provides {{ EventBox }} to
access (extend) {{ Gdk }} functionality. In the following program we can
see that the Ruby works with {{ Gdk::Events }}, however, I can not get
the cursor working. Is this feature available in Ruby, or am I not doing
something right?

±-------------------------------------------------------------+
| require ‘gtk2’ |
| |
| def change_label(event, label) |
| if event.event_type == Gdk::Event::BUTTON2_PRESS |
| if label.text[0].chr == ‘D’ |
| label.text = “I Was Double-Clicked!” |
| else |
| label.text = “Double-Click Me Again!” |
| end |
| end |
| end |
| window = Gtk::Window.new(Gtk::Window::TOPLEVEL) |
| |
| window.set_title “Two buttons” |
| window.border_width = 10 |
| window.signal_connect(‘delete_event’) { false } |
| window.signal_connect(‘destroy’) { Gtk.main_quit } |
| |
| eventbox = Gtk::EventBox.new |
| label = Gtk::Label.new(‘Double-click me!’) |
| |
| eventbox.set_events(Gdk::Event::BUTTON_PRESS_MASK) |
| |
| #??? |
| # eventbox.set_cursor(Gdk::Cursor.new(Gdk::Cursor::HAND1)) ? |
| #??? |
| |
| eventbox.add(label) |
| window.add(eventbox) |
| |
| eventbox.signal_connect(‘button_press_event’) do |w, e| |
| change_label(e, label) |
| end |
| |
| window.show_all |
| Gtk.main |
±-------------------------------------------------------------+

Thank you in advance.

Hi Torli,

That’s not quite how this works. I spent a good deal of time trying to
get this right before I finally found the useful solution.

On Tue, 2009-01-06 at 18:19 +0100, Torli B. wrote:

| if event.event_type == Gdk::Event::BUTTON2_PRESS |
| window.border_width = 10 |
| #??? |
You can only change the cursor for the GDK window, not the GTK window.
In your case, I’d try eventbox.visible_window.cursor = …whatever…

One other thing you might want to consider is not creating the same
cursor all the time. I generally create a set of cursors that I can
reference from everywhere in the code. You’ll also probably want to
investigate the symbolic names as well as the constants. For example,
to get the “appstart” cursor, you need to do:

appstart = Gdk::Cursor.new(Gdk::Display.default, “left_ptr_watch”)

That little gem took me ages to find, so it might save you some
trouble too.

Hope this helps,

ast

Andrew S. Townley [email protected]
http://atownley.org

Hi Andrew,

Andrew, are you using Ruby 1.9.x? I am running 1.8.6. This may be my
problem. Namely, after adding :
±----------------------------------------------------------------+
| eventbox.realize |
| eventbox.window.cursor = Gdk::Cursor.new(Gdk::Cursor::HAND1) |
|# or |
|#eventbox.window.set_cursor(Gdk::Cursor.new(Gdk::Cursor::HAND1)) |
±----------------------------------------------------------------+
I get the following error on line {{ 3 require ‘gtk2’ }} :
±-------------------------------------------------------------------+
| eventbox.rb: line 3 |
| Gtk-CRITICAL **:gtk_widget_realize: assertion GTK_WIDGET_ANCHORED | | (widget) || GTK_IS_INVISIBLE (widget)' failed | | eventbox.rb:26: undefined methodcursor=’ for nil:NilClass |
| (NoMethodError) |
±-------------------------------------------------------------------+

As you see line {{ eventbox.window.cursor =
Gdk::Cursor.new(Gdk::Cursor::HAND1) }} also causes problems. Interpreter
complains about undefined method {{ cursor }}, but I have trouble
finding out where did the {{ window }} came from. Though I can find it
in the book “Foundations of Gtk+ Development” where in the “C” code
example it looks like {{ gtk_window_set_cursor(eventbox->window,
gtk_cursor_new(GTK_HAND1)); }}, I on the other hand can not find it
anywhere in Ruby/GNOME2/Gtk/Gdk documentation.

Regardless, I hope my problem is Ruby1.9.x/1.8.6 related.
Thx, Torli.

Andrew, now it’s time for me to self-followup :). Your suggestion
works!!! I made mistake to call realize before I added it to the top
window.

Thank you for your help,
Torli

Sorry for the self follow-up, but I didn’t have the ability to actually
try this before. I’ve amended the example below and it seems to do what
you intend.

Apologies for missing a couple of ordering issues.

On Tue, 2009-01-06 at 17:30 +0000, Andrew S. Townley wrote:

something right?
| end |
| label = Gtk::Label.new(‘Double-click me!’) |
| |
| eventbox.set_events(Gdk::Event::BUTTON_PRESS_MASK)

eventbox.add(label)
window.add(eventbox)
window.show_all

eventbox.realize
eventbox.window.cursor = Gdk::Cursor.new(Gdk::Cursor::HAND1)

 eventbox.signal_connect('button_press_event') do |w, e|
     change_label(e, label)
 end

 Gtk.main

EOF

reference from everywhere in the code. You’ll also probably want to
ast

Andrew S. Townley [email protected]
http://atownley.org