From: Joe Van Dyk Date: 2006-01-11T22:16:08+09:00 Subject: Re: dialog that pops up when window busy On 1/10/06, David Vallner wrote: > Joe Van Dyk wrote: > > >Hi, > > > >In my window, I sometimes want to prevent the user from doing anything > >while an action is occuring. So I want to disable the window (using > >Gtk::Widget#sensitive). > > > >But I also want to popup a little dialog saying why the window is > >being disabled (and perhaps have a little progress indicator on it). > > > >Are there any Gtk widgets that could help me, or do I need to make a > >custom dialog box for this? > > > > > > > A custom progress dialog should not be hard to implement. If you pop it > up as a modal dialog, you'll also avoid having to desentivize the window > by hand. You'll definitely need a separate thread for a progress dialog, > and possibly wrap whatever you're doing that requires waiting in some > sort of ProgressingTask object to get things completely done. > > That said, I do have a weird hunch I saw some existing implementations > of the problem around, but can't for the heck of it figure out in what > context. Brief googling would indicate that indeed Gtk has a "progress > bar" widget, the documentation to that might provide some insights as to > what you're looking at. And embedding one in a pop-up modal progress > dialog should then be trivial. Bleh, meant to send this to ruby-gnome2, not ruby-talk. :-( Anyway, here's how I solved it. If there's a cleaner way to do it, I'd love to hear about it. class App def initialize Gtk::init @window = Gtk::Window.new "Joe's Crazy Application" @window.set_default_size 300, 300 vbox = Gtk::VBox.new @window << vbox vbox << Gtk::Label.new("Stuff") vbox << Gtk::Label.new("More Stuff") vbox << Gtk::Button.new("Useless button") vbox << Gtk::Button.new("Another Useless button") lock_button = Gtk::Button.new "Lock window for three seconds" vbox << lock_button lock_button.signal_connect("clicked") do # Window gets locked while doing stuff @window.lock do start_time = Time.now # computationally heavy thing there loop do Gtk::process_gui_events # Any way I can get rid of this? rand 100000000 break if Time.now - start_time >= 3 end end end @window.signal_connect("delete-event") { Gtk::main_quit } @window.show_all Gtk::main end end module Gtk # Makes sure that Gtk has a change to draw stuff def self.process_gui_events while Gtk::events_pending? Gtk::main_iteration end end end class Gtk::Window # Locks the window def lock reason = "hold on there buddy", &block self.sensitive = false display_locking_dialog(reason) do block.call end self.sensitive = true end # Displays a locking dialog box with a # pulsing progress bar over the window def display_locking_dialog reason, &block dialog = Gtk::Dialog.new "", self, Gtk::Dialog::MODAL dialog.decorated = false vbox = Gtk::VBox.new reason_label = Gtk::Label.new reason progress_bar = Gtk::ProgressBar.new thread_id = Gtk::timeout_add(100) { progress_bar.pulse } vbox << reason_label << progress_bar dialog.action_area << vbox dialog.show_all block.call Gtk::timeout_remove(thread_id) dialog.destroy end end App.new if __FILE__ == $0