# Can't force any Gtk objects to redraw

**URL:** <https://www.ruby-forum.com/t/cant-force-any-gtk-objects-to-redraw/217727>\
**Category:** Ruby-Gnome 2\
**Created:** [March 10, 2012, 7:26am UTC](https://www.ruby-forum.com/t/cant-force-any-gtk-objects-to-redraw/217727 "2012-03-10T07:26:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [March 10, 2012, 7:26am UTC](https://www.ruby-forum.com/t/cant-force-any-gtk-objects-to-redraw/217727/1 "2012-03-10T07:26:41Z")

</div>

Hi y’all:

I’m having a problem with getting anything to paint on the screen  
IMMEDIATELY. Here’s what I’m trying to do:

I’m downloading the names of all my rubygems and version numbers using  
their API. So, its making about 20 http requests in a row. When the  
user clicks the button to list his/her rubygems, the program seems to  
hang while these names/versions are being downloaded. I need to have  
the program oputput something during this time, so I tried updating a  
Gtk::TextView:

def refresh()  
return unless @gems = @api.get\_obj\_url("/api/v1/gems.yaml")  
@gems.each do |gem|  
gem\_info = @api.get\_obj\_url("/api/v1/versions/#{gem[‘name’]}.yaml")  
@main.shell.buffer.text += "loading gem: " + gem[‘name’] + “\n”  
end  
end

I tried for hours to get the text to update on the screen while each gem  
is being downloaded. I tried:

@main.shell.queue\_draw  
@main.builder[“scrollShell”].queue\_draw  
@main.builder[“window1”].hide  
@main.builder[“window1”].show\_all  
@main.shell.show

But nothing has any effect. It always updates the textbox AFTER all the  
gems are downloaded.

So I tried making a popup window with a progress bar on it. But I had  
the same problem. I can’t disply the window until AFTER the loop  
completes.

What am I missing?

Thanks,  
Eric

---

<div class="post-metadata">

**Author:** ![ericrchr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/8baadc/32.png) [@ericrchr](https://www.ruby-forum.com/u/ericrchr)\
**Post date:** [March 10, 2012, 8:30am UTC](https://www.ruby-forum.com/t/cant-force-any-gtk-objects-to-redraw/217727/2 "2012-03-10T08:30:11Z")

</div>

Call this after telling a widget to do something:

module Gtk  
def self.clear\_queue  
while events\_pending? do main\_iteration\_do(blocking = false) end  
end  
end

2012/3/9 Eric C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![ericrchr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/8baadc/32.png) [@ericrchr](https://www.ruby-forum.com/u/ericrchr)\
**Post date:** [March 10, 2012, 9:26am UTC](https://www.ruby-forum.com/t/cant-force-any-gtk-objects-to-redraw/217727/3 "2012-03-10T09:26:13Z")

</div>

Hi Eric,

```
it seems that the requests you're doing are synchronous. Most likely 

```

what Ian has suggested works but still, if you have some downloading to  
do you better put it on another thread.

in refresh, try to do something like this instead of what you’ve  
wrote:gem\_infos = []def refresh  
return unless @gems = @api.get\_obj\_url(“/api/v1/gems.yaml”)  
@gems.each do |gem| @main.shell.buffer.text += “loading gem: " +  
gem[‘name’] + “\n” Thread.new do gem\_infos \<\<  
@api.get\_obj\_url(”/api/v1/versions/#{gem[‘name’]}.yaml") end end  
end

This is not a “polite” thing to do with threads but it should give you  
an idea on how to approach a problem like this (if you have a heavy task  
you should put it on a different thread anyway, no matter if you need to  
do that for interface reasons)Andrea

–

> **[using (IMHO)](https://usingimho.wordpress.com/)**
>
> Andrea Dallera 's blog

> **[bolthar - Overview](https://github.com/bolthar)**
>
> bolthar has 18 repositories available. Follow their code on GitHub.

From: “Ian McIntosh” removed\_email\_address@domain.invalid  
To: removed\_email\_address@domain.invalid  
Cc:  
Date: Fri, 9 Mar 2012 23:29:23 -0800  
Subject: Re: [ruby-gnome2-devel-en] Can’t force any Gtk objects to  
redraw

---

<div class="post-metadata">

**Author:** ![ericrchr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/8baadc/32.png) [@ericrchr](https://www.ruby-forum.com/u/ericrchr)\
**Post date:** [March 10, 2012, 11:49pm UTC](https://www.ruby-forum.com/t/cant-force-any-gtk-objects-to-redraw/217727/4 "2012-03-10T23:49:17Z")

</div>

Excellent! Thanks.

Ian,

I tried a similar solution earlier, but it only showed the window  
without anything in it. Also, I read that using that method may make MS  
Windows crash (big suprise!).  
But using a thread worked perfectly. In  
fact, when I put the downloading code in its own thread, I didn’t even  
need to output text to show the progress because my listview that shows  
all the gems was being updated in REAL TIME!!! Awesome.

This was absolutely the best result possible because now when someone  
clicks the tab to see remote gems, the listview comes alive and gems  
start  
popping-up. Its perfect.

Here’s the version that works:

def refresh()  
return if @t  
@t = Thread.new do |t|  
@main.shell.buffer.text += “\nContacting [rubygems.org](http://rubygems.org)…”  
self.model.clear  
return unless @gems = get\_obj\_url(“/api/v1/gems.yaml”)  
@gems.each do |gem|  
gem\_info = get\_obj\_url(“/api/v1/versions/#{gem[‘name’]}.yaml”)  
gem\_info.each do |info|  
self.add\_row(RUBY\_ICON, “#{gem[‘name’]} (#{info[‘number’]})”)  
end  
end  
t.join  
end  
@t = false  
end

I only have a few more things to do now, and I’ll be finished. 🙂  
HaHaHa

Yours,  
Eric

---

<div class="post-metadata">

**Author:** ![ericrchr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/8baadc/32.png) [@ericrchr](https://www.ruby-forum.com/u/ericrchr)\
**Post date:** [March 13, 2012, 7:05pm UTC](https://www.ruby-forum.com/t/cant-force-any-gtk-objects-to-redraw/217727/5 "2012-03-13T19:05:38Z")

</div>

Le 10 mars 2012 23:49, Eric C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) a  
crit :

> all the gems was being updated in REAL TIME!!! Awesome.  
> @t = Thread.new do |t|  
> end  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).  
> [https://lists.sourceforge.net/lists/listinfo/ruby-gnome2-devel-en](https://lists.sourceforge.net/lists/listinfo/ruby-gnome2-devel-en)

Hi.

I always thought that calling Gtk methods in a thread was a bad idea…  
IS it not the case anymore ?

When I need to do work in a thread and update a gtk widget I use the  
Queue  
class.  
The working thread push “event” in the queue whereas in gtk main loop  
GLib::Timeout  
pops events from the queue.
