RE: GTK Progress bar: assistance pls.



/*MYSTERIOUS CODE [FOR ME] -- WORKS !! :-)*/
while (gtk_events_pending ())
{
     g_print("[.]");
     gtk_main_iteration ();
}

Vijay:

Hi, all. How convinient! I was looking for it. Thanks!

I do understand the reason though. You're running a single thread program, instruction are run in a sequence. 
Without that fraction of code, time_out callback which you registered will be call when you exit the 
iteration and returned control to the GTK system. I am new to GTK, but I guess the gtk_main() has a logic 
like this:

pseud-code

void gtk_main()
{
      while(TRUE){
          // any portion of windows need to be paint?
          // any timer event, keyboard event, mouse event ....?
          //
          if( gtk_events_pending () ){
               gtk_main_iteration ();
               
               if ( gtk_main_quit_is_called )
                   break;
          }else if( there is any registered idle action)
              handle_idle_action ()
          else
              sleep (200); // no need to keep the system busy do nothing.
     }
}

while gtk_main_iteration () essentially retrieve an event from events queue, translate it , dispatch it ....


If you want to update user interface (respond to GTK signal/events) while performing a very large job without 
feeling much delay, you either do the job in a thread in which case the operating system will guarantee both 
your main thread and the work thread will have a share of cpu time, or you poll for pending events once in a 
while and give the GTK system a chance to handle them, this is essentially what the above code fraction do.

HTH.

Lance








Date: Mon, 7 Jan 2008 17:18:08 +0530
Subject: Re: GTK Progress bar: assistance pls.
From: vijayasarathy setsindia net
To: dunno stoptrick com
CC: gtk-app-devel-list gnome org





Hey Carlo,

Thanks man. Your idea works, but .... I am still not able to figure out
how  it works .....


Let me first tell you all what I have done.


I have a button which when clicked shall start iterating from 0 to
1000[say], and for each iteration, does some work[counts another variable
j for some time].

Total work to be done here = 1000 * counting js

Periodically I want my progress bar to keep me updated on how much of this
above work has been completed.

I compute fraction = (i+1)/1000. This much of work has been done at that
point of time.

I have written a time out function for the progress bar[which times out
when fraction is >=0.99] which will be called every 1 second. This
function looks at the fraction of work done, and update the fraction at
the progress bar accordingly.

Problem:
for every iteration in i[from 1 to 1000], I kept updating value fraction,
and passed this fraction to the progress bar inside the for loop for
getting prgress bar updated. I always saw that only when the fraction was
0.99[that is when the work was complete] did control pass to progress bars
timeout function, and so the first value to progress bar was itself 0.99.
So, progress bar waited for operation to finish and then displays a fully
completed picture.

The problem was then solved [Thanks to everyone who contributed, special
thanks to Carlo] and here is the code that updates progress bar while the
work is on[and not only after the work is complete]:

****************START CODE ************************************************
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>

//C Related includes
#include<unistd.h>
#include<stdlib.h>

#include "callbacks.h"
#include "interface.h"
#include "support.h"

typedef struct
{
      GtkWidget *pbar;
      gdouble fraction;

}ProgressData;

void
on_button1_clicked                     (GtkButton       *button,
                                        gpointer         user_data)
{
    GtkWidget *wdgt_progress_bar;
    ProgressData *pdata;
    gint i = 0;
    gint j = 0;
    gint range = 1000000;

    wdgt_progress_bar = lookup_widget(GTK_WIDGET(button),"progressbar1");

    pdata = (ProgressData *)g_malloc0(sizeof(ProgressData));
    pdata->pbar = wdgt_progress_bar;

      //Call progress_timeout() every 1 second.
    g_timeout_add (100, progress_timeout, pdata);

    for(i=0;i<range;i++)
      {
              //Do work w1.
              //g_print("(%d)",i);
              while(j<100000)//To kill time, keep counting until a lakh
                      j++;
              j = 0;//Make j 0 for the next loop.

              //Update fraction
              pdata->fraction = (gdouble)i/(gdouble)(range);

              g_print("(%f)",pdata->fraction);

              /*MYSTERIOUS CODE [FOR ME] -- WORKS !! :-)*/
              while (gtk_events_pending ())
              {
                      g_print("[.]");
                      gtk_main_iteration ();
              }


      }//End for i = start_count to end_count

}

/* Update the value of the progress bar so that we get
 * some movement */
static gboolean progress_timeout( gpointer data)
{
      ProgressData *pdata = (ProgressData *)data;
      gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar),
pdata->fraction);

      if(pdata->fraction>=0.99)//If work is complete.
              return FALSE;//Stop updating.
      else//If work is not complete.
              return TRUE;
}

****************************END CODE ***************************************


I am still not clear as to how this works.

Inclusion of this piece of code is what made it work.

while (gtk_events_pending ())
{

  gtk_main_iteration ();
}

1. What does gtk_events_pending() signify ? for the code running when the
button is clicked, is the timeout function of the progress bar a pending
event ?

2. What is the use of gtk_main_iteration() ? From the docs, I see that it
calls gtk_main() once. As I know when gtk_main() is called, the program
automatically starts listening to X events.


3.Why should this be put into the while loop of gtk_events_pending() ?

4. When does this while loop end ? Is that random [because that is how it
looked to me when I put values into the while loop and observed fraction
values at which this was called]

Carlo, it will be good if you can throw more light on how this code
snippet made it work.


Coming back to discussion with Dan, I still dont understand how you would
say memory is being leaked when I malloc(50) and then use only less than
that from the return value of get_text[that is what was returned from the
text box in UI]. [By the way, memory wasted is some_size -
strlen(something_else) :-)].

I feel allocating space to variables which will receive values whose size
it doesnt know is important becuase the program atleast deals with memory
which it knows about. Comment on that statement Dan.


Thanks you very much folks, this is a great place to be part of.

One might wonder why g++ compiler when most things I use is C. The point
is, there are certain modules which have been developed in C++ and I
wanted the compiler to be consistent across code. Moreover, g++ is more
stringent compared to gcc when it comes to usage of variables.

Vijay

On Mon, January 7, 2008 4:18 pm, Dan H wrote:
On Mon, 7 Jan 2008 14:51:11 +0530 (IST)
vijayasarathy setsindia net wrote:

IN REPLY TO DANS COMMENTS:


1. I am using the g++ compiler and g++ doesnt let a gpointer[return
type of g_malloc0()] or a void pointer point a gchar or a ProgressData
pointer. That is why the typecast.

Ah, so you're using it in C++ mode. Yes, C++ requires the cast, C
doesn't.


2. I need more explanation here:


txt_start_count = (gchar
*)gtk_entry_get_text(GTK_ENTRY(wdgt_start_count));



Useless (possibly dangerous) cast, and you're leaking the memory
g_malloced() above.


Why do you think memory is leaked ?


Because this is, briefly, what you do in your code:


foo = malloc(some_size) foo = something_else

This leaks some_size bytes of memory. The question is: What is the
purpose of g_malloc() in the first place?

I have already done a
lookup_widget on wdgt_start_count. gtk_entry_get_text() returns a const
gchar * value while mine is a gchar *, and that is why the typecast.

Well then declare txt_start_count as a const char as well.


The typecast is both unneccessary and dangerous in the (unlikely) event
that some new version of GTK+, gtk_entry_get_text() returns something
other than a gchar *.

You really need to get your C act together before embarking on such a
project.

--D.
_______________________________________________
gtk-app-devel-list mailing list gtk-app-devel-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
**************************************************************************
***********
DISCLAIMER
This e-mail and any files transmitted with it are for the sole use of the
intended recipient(s) and may contain confidential and privileged
information. Any use,distribution,copying or disclosure by any other
person is strictly prohibited. If you have received this transmission in
error please notify SETS immediately either by replying to this e-mail or
by telephone +91-44-28205655 and then delete this e-mail. The sender does
not accept any responsibility for any damage which you sustain as a
result of software viruses or malicious programs. You should therefore
scan attachments (if any) prior to opening them.
*************************************************************************
***********









Vijayasarathy
Senior Research Associate
SETS

***************************************************************************
DISCLAIMER
This e-mail and any files transmitted with it are for the sole use of
the intended recipient(s) and may contain confidential and privileged
information. Any use, distribution, copying or disclosure by any other
person is strictly prohibited. If you have received this transmission
in error please notify SETS immediately either by replying to this e-mail
or
by telephone on +91-44-28205655 and then delete this e-mail.
The sender does not accept any responsibility for any damage which
you sustain as a result of software viruses or malicious programs.
You should therefore scan attachments (if any) prior to opening them.
**************************************************************************



_________________________________________________________________
Windows Live Photo gallery 数码相机的超级伴侣,轻松管理和编辑照片,还能制作全景美图!
http://get.live.cn/product/photo.html


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