Forum: Ruby-Gnome 2 refresh Gtk::Image (newb question)

Posted by jake kaiden (lljk)
on 2010-05-25 21:17
hello all,
  first let me say that i'm a complete programming and ruby newbie -
haven't done any programming since writing stuff in basic on my TI99-4a,
circa 1984 - so please forgive any questions or code (!) that seem
ridiculous.
  here's my story/questions....
  i'm working on a simple mp3 player written in ruby, using gstreamer
and gtk+...  really pretty straightforward - not supposed to do much
except load and save a playlist, and show some playback controls and the
cover art.  i've got it doing all of that alright, only problem is i
can't figure out for the life of me how to update the album art when the
song changes, either from a 'next' button click, or reaching the end of
the song.  i've googled the b-jaysus out of refreshing gtk images, and
come up with some different ideas (event boxes, drawing areas...) but i
can't seem to get anything to work.
  i imagine this is something really simple that for some reason i just
can't figure out.  it seems that i have to jump out of the gtk.main loop
in order to update the cover.  i know that a Gdk (that's "d," not "t,")
window has an invalidate method, and a queue method, and it seems like
that could be a solution - or maybe through triggering an eventBox...
or through some other blatently obvious solution that i have no idea
about.
  here's a look at what i think should be the relevant code... thanks in
advance for any and all help.

  everything is inside a Gtk::Window - here's the bit about the album
art...

code snippet:
 ...
   ## "player.img" is dynamic, based on the current song ##
   coverpix = Gdk::Pixbuf.new(player.img, 196, 196)
  cover = Gtk::Image.new(coverpix)
  cover.show
  artBox = Gtk::EventBox.new.add(cover)
  artBox.show

  box = Gtk::VBox.new(false,0)
  box.pack_start(artBox,true,true,2)
  box.pack_start(bbox,false,false,2)
  box.show

  window.add box
  window.show

  Gtk.main
 ...

  i've tried using this bit of code as a 'refresh' method, and also
inside the next button's EventBox block - when i add a "puts player.img"
in there to see what's happening under the hood, i don't see anything
until i stop the program (breaking the gtk main loop,) at which point
any and all of the correct image filenames appear for the songs played.

  again, sorry if this is a boneheaded question, but i've been up high
down and low searching and experimenting with no luck - any ideas would
be appreciated...

-jk
Posted by Michal Suchanek (Guest)
on 2010-05-25 23:20
(Received via mailing list)
Hello

I suspect that the issue you are experiencing stems from Gtk::Image
widget not updating on changes to the Gdk::Image it is displaying.

The simplest way to work around this is to create a new Gdk::Image
when the cover art changes and assign it to the Gtk::Image widget.

The other way would be to invalidete the widget so that it gets
repainted eventually or force it to repaint even.

If your problem is not solved by this then I suggest you post the
exact code which demonstrates it.

HTH

Michal
Posted by Vincent Carmona (vinc-mai)
on 2010-05-25 23:34
(Received via mailing list)
Hi.

I have had the same issue with my music player. You just call the
Gtk::Image#show each time the image is updated.

Vincent

P.S.: on your snippet, you don't have to call the show method on all
Gtk widgets instead you can call show_all on the main container once
other widgets have been added (i.e. window.show_all instead of all the
show methods)

2010/5/25, Michal Suchanek <hramrach@centrum.cz>:
Posted by Oasjxzcoijoasjdflas Asdfizxcv kklas (gorhas123)
on 2010-05-26 00:48
(Received via mailing list)
Hello!

Take a look at:
http://www.raditex.nu//websvn/listing.php?repname=kurssrc.Exempel&path=%2FRubyStateMachine%2F#_RubyStateMachine_

First start "ruby ./DoorServer.rb"  And then "ruby ./GtkDoorClient.rb"

1) This implement a simple state machine
    - It shows how you should switch images upon state changes

2) I demonstrate how you could split your applications in client 
server...
    - Your userinterface could be the client and the player could be the
server

Göran

2010/5/25 Jake Kaiden <ruby-forum-incoming@andreas-s.net>
Posted by jake kaiden (lljk)
on 2010-05-26 12:45
hi folks -

  thank you all very much indeed - now i've got some things to play 
with!  going to fiddle around some with all of your suggestions and see 
what i can come up with.  if i can't get things working i'll post back 
with more complete code, and when i do get it working i'll make sure to 
post the solution that worked for me.

  thanks again,
  viva the ruby forum!

  jk
Posted by jake kaiden (lljk)
on 2010-05-26 20:26
hello again,

  first let me thank you all for your suggestions, they got me thinking 
and experimenting, and i've now got some code working in an example 
program that i think will solve my problem.  i ended up clearing the 
EventBox with the #remove method, then recreating the Gtk::Image as 
suggested, and then adding this to the now empty EventBox.  not sure how 
'elegant' it is, but it works!
  i've included the code to the sample program - feel free to let me 
know if you think something looks just plain dumb!  i'll give a quick 
shout back when i get this worked into the mp3 player.

  thanks again for the ideas...

peace, love, rock and roll -

jk


########## CODE #######################################

require 'gtk2'

class Pics
  attr_accessor :pile, :picindex, :atBat, :image, :box, :window

def initialize
  @window = Gtk::Window.new()
  @window.signal_connect("destroy"){Gtk.main_quit}
  pic1 = "TradyBlix.png"
  pic2 = "ride.png"
  pic3 = "konichiwa.jpeg"
  @pile = [pic1, pic2, pic3]
  @picindex = 0
  self.getImage
  @box = Gtk::EventBox.new.add(@image)
end

def batterUp
  @box.remove(@image)
  @picindex = @picindex + 1
  @picindex = 0 if @picindex == @pile.length
  self.getImage
  @box.add(@image)
  @box.show
end

def getImage
  @atBat = @pile[@picindex]
  img = Gdk::Pixbuf.new(@atBat, 200, 200)
  @image = Gtk::Image.new(img)
  @image.show
end

end # class Pics

pics = Pics.new
  pics.box.signal_connect("button_press_event"){pics.batterUp}
  pics.window.set_default_size(200, 250)
  pics.window.add(pics.box)
  pics.window.show_all

Gtk.main

############ EOF ##############################
Posted by jake kaiden (lljk)
on 2010-05-26 23:55
...the eagle has landed.

  thanks all...

j
Posted by Michal Suchanek (Guest)
on 2010-05-27 09:43
(Received via mailing list)
On 26 May 2010 20:26, jake kaiden <ruby-forum-incoming@andreas-s.net> 
wrote:
> hello again,
>
>  first let me thank you all for your suggestions, they got me thinking
> and experimenting, and i've now got some code working in an example
> program that i think will solve my problem.  i ended up clearing the
> EventBox with the #remove method, then recreating the Gtk::Image as
> suggested, and then adding this to the now empty EventBox.  not sure how
> 'elegant' it is, but it works!
>  i've included the code to the sample program - feel free to let me
> know if you think something looks just plain dumb!  i'll give a quick

As I wrote earlier it suffices to replace the Gdk::Pixbuf, the
GtkImage can stay:

@@ -7,11 +7,9 @@
 def initialize
  @window = Gtk::Window.new()
  @window.signal_connect("destroy"){Gtk.main_quit}
- pic1 = "TradyBlix.png"
- pic2 = "ride.png"
- pic3 = "konichiwa.jpeg"
- @pile = [pic1, pic2, pic3]
+ @pile = Dir::glob("104*") + Dir::glob("2003*")
  @picindex = 0
+ @image = Gtk::Image.new
  self.getImage
  @box = Gtk::EventBox.new.add(@image)
 end
@@ -28,8 +26,7 @@
 def getImage
  @atBat = @pile[@picindex]
  img = Gdk::Pixbuf.new(@atBat, 200, 200)
- @image = Gtk::Image.new(img)
- @image.show
+ @image.pixbuf = img
 end

 end # class Pics


HTH

Michal
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.