Re: Calling GUI function from Thread



Hi,

Fortunately I had this option of passing a user_data parameter to the callback function. Your solution did work and I was able to call the dispatcher function from the callback. However, after setting the text in the label the program did not return back to the callback fn. resulting in a segmentation fault. Actually, this callback function is being continuously called by the API until the final result is available. During every call it sends a guidance status to the callback fn. which requires the user to respond accordingly after which it continues its processing. Please see if you could suggest some solution.

Thanks and Regards,
Taha

On 9/11/07, Matt Fischer <mattfischer84 gmail com> wrote:
On 9/10/07, Taha Ali <tahaarifali gmail com> wrote:
>
> Hi,
>
> Thanks for the reply. Actually, the API that I am using wants me to register
> a callback function that would report to me the progress of the function
> that I have called in my thread. This callback is not able to see the
> Glib::Dispatcher variable from my application class.  The pseudo code is
> like this:
>
> class Application
> {
>          ...................
>          -------------------
>             Glib::Dispatcher report_message_signal;
>             static some_callback_func(arg1, arg2, arg3);
>          ...................
>          -------------------
>          ...................
>          -------------------
> }
>
> main()
> {
> ----------
> ----------
> Register_API_Callback_func(some_callback_func, .......);
> ----------
> ---------
> }
>
>
> on_button_clicked()
> {
> Glib::Thread::create(thread_function ......);
> }
>
> thread_function()
> {
> ---------
> ---------
> API_Function(); //Takes around 10 seconds
> ----------
> ----------
> report_message_signal();
> ---------
>
> --------
> }
>
> some_callback_func(Message)
> {
>
> //This function is internally called by the API giving info about the
> progress that API_Function
> //is making and it is from here that I have to set text, in order to report
> guiding messages, in the
> //label. I know that this is not right but what other options do you think I
> have.
>
> }
>
> Thanks and Regards,
> Taha
> _______________________________________________
> gtkmm-list mailing list
> gtkmm-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtkmm-list
>
>

Most well-designed APIs set up callbacks so that they have a
user-defined data parameter.  If yours does, it can be used to pass in
the necessary data.  Something like:

class Application
{
    struct UsefulData {
          Glib::Dispatcher dispatch;
          Glib::ustring progress_text;
    };

    Gtk::Label label;
    UsefulData data;


    Application()
    {
         data.dispatch.connect( sigc::mem_fun( *this,
&Application::mainloop_callback ) );
    }

    void mainloop_callback()
    {
         label.set_text( data.progress_text );
    }

    static void some_callback_func( arg1, arg2, arg3, void *user_data )
    {
         .......

         UsefulData *data = "">         data->progress_text = ....
         data->dispatch();
    }

    void on_button_clicked()
    {
         register_API_callback_func( &Application::some_callback_func, &data );

         Glib::Thread::create( &Application::thread_func );
    }

    void thread_func()
    {
          API_function();

          // could call a final time from here if you want, too, as in
your example
         data.progress_text = ....
         data.dispatch();
    }
};

Depending on how thready your application is, you'd probably want to
guard 'data' with a mutex or some such, but you get the idea.  If
you're not lucky enough to have a user data parameter, you have less
options.  Basically, you want to make the dispatcher visible to the
callback somehow.  The most straightforward solution would be to make
the dispatcher and any associated data static variables as well,
although this might pose a problem if you have more than one
Application object trying to run at once.  In that case, you might be
sort of SOL.

But in general, you need to find some solution that doesn't involve
calling Gtk functions from outside the mainloop.  Using a Dispatcher
in some capacity, and finding a suitable way to pass the data into the
mainloop, is probably your best bet.

--Matt



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]