Updating a GtkTreeView - which approach should I choose?



Hello there,

I'm writing a quite simple GTK+ application, which is supposed to update
software installed on the system. Its main part is a GtkTreeView connected to
a model describing every app the user wants to update. It (i.e. the view)
contains 5 columns: Name, Installed, Latest, Status, Progress. The interface is
really trivial right now - it contains 2 buttons, one for updating all apps and
one for exiting the program ;) I've got trouble with the button used for
updating the apps.

What the click should result with is:

- check which version of given software is installed on the user's computer,
- print that version in the column "Installed",
- check the latest version of given software (through libcurl),
- print that version in the column "Latest",
- do the above 4 steps for all apps the user has defined,
- meanwhile, update the "Status" column to inform the user what the program is
  doing.

The problem is how to call the updating function to force those columns to be
updated immediately after any column in the model is changed. What I tried is:

(NOTE: I'm actually a GTK+ newbie, so I may be breaking some basic rules of
writing a GTK+ app without even thinking about it :))

1. Simply connect the updating function to the updating button, like this:

--------------------------------------------------------------------------------
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(update_apps), NULL);
--------------------------------------------------------------------------------

This is not what I wanted as the view isn't updated at all until the updating
function returns (i.e. all apps are checked). Besides, the updating button is
pressed until the return - and I don't want it to be constantly pressed.

2. Call the updating function as a separate thread, like this:

--------------------------------------------------------------------------------
g_thread_init(NULL);
(...)
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(update_thread), NULL);

update_thread():
(...)
g_thread_create((GThreadFunc) update_apps, data, FALSE, NULL);
(...)

update_apps():
(...)
gdk_threads_enter();
gtk_list_store_set(..., ..., ..., ..., ...);
gdk_threads_leave();
--------------------------------------------------------------------------------

This works oddly. One run it works just as I want it to (values are displayed
immediately after they're set), the other one the values or not updated until
some event has to be processed by GTK+, e.g. I change the active window, move
the mouse pointer around etc. So for example, at the beginning the status column
is changed to "Checking installed version..."; then, if I don't touch my mouse
nor my keyboard, nothing seems to be happening, and then when I move the mouse,
all apps are already updated.

3. Using an idle function artificially emitting the "row-changed" signal to the
tree view, like this:

--------------------------------------------------------------------------------
g_idle_add((GSourceFunc) update_tree_view, NULL);

update_tree_view():
(...)
gtk_tree_model_row_changed(..., ..., ...);
(...)
--------------------------------------------------------------------------------

This works just as I want it to, however, it pumps my CPU usage to 99%
immediately after the program starts and this is unacceptable in my case.

So, you've got quite a complete log of what I have been trying and what has
crossed my mind :) I'll be glad if you could give me any clues - what exactly
should I do or maybe which docs should I read or anything that I might find
useful in solving this problem.

Thanks in advance for any hints,
Michal Kepien



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