query on create_from_file and gdk_threads_enter() and gdk_threads_leave()

View: New views
2 Messages — Rating Filter:   Alert me  

query on create_from_file and gdk_threads_enter() and gdk_threads_leave()

by Robert Bui-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
Hello all,

   I am trying to load multiple images  (one after another) onto a Gtk::Image widget. I have multiple background threads that looks for files at different location on disk. As soon as there is a new file, one of these would add the filename (enqueue) to the GAsyncQueue shared by the threads. Once enqueue is done, the thread would fire a signal which in turn would call the callback function in the main thread to display the image.
   The image actually displays but the whole GUI just hang.
   No exceptions were caught.

   Now, if I enclose the code inside ondisplayDocumentSignal (from create_from_file() to set()) around gdk_threads_enter() and gdk_threads_leave(), then it seems to work, ie the images get displayed correctly.
1. Why is this so?
2. Am I doing it correctly?
3. Why do I need to do this? I thought the main thread has control of all the GTK widgets as well as GDK?




void DocumentProcessor::viewImage(std::string imageFilename)
{
    ...
    this->displayQueue_->enqueue(imageFilename);
    this->displayDocumentSignal_();
    ...
}


Glib::RefPtr<Gdk::Pixbuf> pixImage;   //Global for now .....

main()
{
    ...
    if(!Glib::thread_supported()) Glib::thread_init();
    documentIndexer->displayDocumentSignal().connect(sigc::ptr_fun(ondisplayDocumentSignal));
    ...
    refXml->get_widget("main_window", main_win);
    main_win->show_all();
    if (main_win)
    {
        kit->run(*main_win);
    }
}



void ondisplayDocumentSignal()
{
    Gtk::Image            *indexImage;
    std::string             filename;
    
    refXml->get_widget("indexImage", indexImage);
    if (!indexImage)
    {
        throw std::runtime_error("Couldn't find indexImage in captivator.glade");
    }   
    if (indexViewQueue!= NULL && indexImage != NULL)
    {
       
        filename = indexViewQueue->dequeue();
        if (!g_file_test(filename.c_str(), G_FILE_TEST_IS_SYMLINK) &&
                (!g_file_test(filename.c_str(), G_FILE_TEST_IS_DIR)))
        {
            try
            {
                pixImage.reset();
                pixImage = Gdk::Pixbuf::create_from_file(filename);
                indexImage->set(pixImage);   
            }
            catch (Gdk::PixbufError &e)
            {
                Logger::log()->write("ondisplayDocumentSignal: Gdk::PixbufError");
            }
            catch (Glib::FileError &e)
            {
                Logger::log()->write("ondisplayDocumentSignal: Glib::FileError");
            }
            catch (...)
            {
                Logger::log()->write("ondisplayDocumentSignal: unknown error");
            }
        }
    }
}


Let us help with car news, reviews and more Looking for a new car this winter?
_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: query on create_from_file and gdk_threads_enter() and gdk_threads_leave()

by Chris Vine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 22 Jun 2009 16:47:30 +1000
Robert Bui <vncoder@...> wrote:

> Hello all,
>
>    I am trying to load multiple images  (one after another) onto a
> Gtk::Image widget. I have multiple background threads that looks for
> files at different location on disk. As soon as there is a new file,
> one of these would add the filename (enqueue) to the GAsyncQueue
> shared by the threads. Once enqueue is done, the thread would fire a
> signal which in turn would call the callback function in the main
> thread to display the image. The image actually displays but the
> whole GUI just hang. No exceptions were caught.
>
>    Now, if I enclose the code inside ondisplayDocumentSignal (from
> create_from_file() to set()) around gdk_threads_enter() and
> gdk_threads_leave(), then it seems to work, ie the images get
> displayed correctly. 1. Why is this so? 2. Am I doing it correctly?
> 3. Why do I need to do this? I thought the main thread has control of
> all the GTK widgets as well as GDK?

No, you are not doing it correctly.
 
A slot will execute in the thread which calls the signal to which it
is connected. It is just an encapsulated callback.  You need to use
Glib::Dispatcher in order for the slot to execute in the main GUI
thread.

Make sure all your calls to Glib::Dispatcher::connect(), and anything
you do to the sigc::connection object it returns, are in the main GUI
thread. If the only thing that is called in the worker threads on the
Dispatcher object is Glib::Dispatcher::emit() or
Glib::Dispatcher::operator()() then it will work fine.

Chris

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list