Gtk::ProgressBar set_fraction doesn't work

  • Thread starter Patrick Plattes
  • Start date
P

Patrick Plattes

Hello,

i have some problems with the Gtk::progressBar. I download a file and i
want to show a progressbar. The method below creates a new dialog with a
bar and starts the download for each file. The puts-line work very well
and i can see a dialog, there is no update. Does anybody know whats
going wrong?

Thanks to all the people in this great community,
Patrick


def download_podcasts(liststore_podcasts)
dialog = Gtk::Dialog.new("Download",
$main_application_window,
Gtk::Dialog::DESTROY_WITH_PARENT)

bar = Gtk::progressBar.new
bar.fraction = 0.0

dialog.vbox.add(bar)
dialog.show_all

liststore_podcasts.each do |model,path,row|
row[3].download do |received, total|
bar.fraction = received.to_f / total.to_f
bar.text = (bar.fraction * 100).to_s + "%"
puts received.to_s + " / " + total.to_s + " = "
+ bar.fraction.to_s
end
end

dialog.destroy
end
 
K

Kouhei Sutou

Hi,

In <[email protected]>
"Re: Gtk::progressBar set_fraction doesn't work" on Sun, 3 Dec 2006 20:35:11 +0900,
Paul Lutus said:
The thread in which your process is running, that would update the progress
bar, is busy downloading your file, so it cannot update the progressbar
dislay. This is a very common problem, normally solved by creating a
separate thread to perform the download, thus freeing the display thread to
perform updates. Unfortunately, because of how threads are implemented in
Ruby, this approach often doesn't work.

I have not had any success updating progress bars using worker threads and
the Qt GUI library, you may have a different experience with
GTk:progressBar.


Gtk.idle_add may help you.


Thanks,
 
P

Patrick Plattes

Paul said:
I have not had any success updating progress bars using worker threads and
the Qt GUI library, you may have a different experience with
GTk:progressBar.

I found an interesting link:

"You are probably doing all the changes within a function without
returning control to gtk_main(). This may be the case if you do some
lengthy calculation in your code. Most drawing updates are only placed
on a queue, which is processed within gtk_main(). You can force the
drawing queue to be processed using something like:

while (g_main_context_iteration(NULL, FALSE));

inside you're function that changes the widget.

What the above snippet does is run all pending events and high priority
idle functions, then return immediately (the drawing is done in a high
priority idle function)." [http://www.gtk.org/faq/#AEN602]

I don't see how i can call g_main_context_iteration in ruby. Any idea?

Thanks,
Patrick
 
K

Kouhei Sutou

Hi,

2006/12/4 said:
"You are probably doing all the changes within a function without
returning control to gtk_main(). This may be the case if you do some
lengthy calculation in your code. Most drawing updates are only placed
on a queue, which is processed within gtk_main(). You can force the
drawing queue to be processed using something like:

while (g_main_context_iteration(NULL, FALSE));

inside you're function that changes the widget.

I don't see how i can call g_main_context_iteration in ruby. Any idea?

while Gtk.events_pending?
Gtk.main_iteration
end


Thanks,
 
R

richard.j.dale

Paul said:
I have not had any success updating progress bars using worker threads and
the Qt GUI library, you may have a different experience with
GTk:progressBar.
I can't help with the original GTK question. But in QtRuby you would
use a Qt::Timer that allows you to specify a ruby method as a 'slot' to
be called periodically. In the slot called by Qt::Timer, download a
single file, update the progress bar and return. That way control can
return to Qt's main loop, and events can be handled - otherwise the GUI
will just freeze while you do what might be a lengthy download of lots
of podcasts.

-- Richard
 
R

richard.j.dale

Paul said:
Yes, tried that method. Doesn't work for a single file, the original
objective. The reason AFAICS is the timer can't easily preempt the file
download while it is under way, and when it can, it produces now
information that the display routines will use to update the display, but
only after the file download is finished.

Your suggestion works for a task consisting of a series of file downloads,
and a progress bar that indicates the total progress for all the files, and
a timer that initiates each new file download at intervals. Yes, that
works.
To do that you would need to create a socket, and then use a
Qt::SocketNotifier of Type Read to monitor it. The SocketNotifier emits
a signal 'activated(int)' when there is something to read on the
socket. So in the slot connected to the activated signal, you would
read from the socket, update the progress bar according to the bytes
read and return.

-- Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top