I am trying to make an application which renders a window of several rows and columns, and update it using some input I receive from command line. I am able to add rows based on the input, but the problem I am facing is that the GUI only shows up in the end once it(i.e GtkListStore) is updated.
I have found that is expected, and to make it work as expected(i.e updating the GUI on the go, as the gtkListStore is being updated) I need to use threads, I have found some tutorials but they are all explained in python. Since I am extremely new to gtk and already know very less about it, I am unable to connect and understand what do I exactly need to do to make my gtk application written in C work as expected.
What I have tried:
This is the code, apologies for the large block of code.
#include <stdio.h>
#include <gtk/gtk.h>
#include <stdlib.h>
struct retObj {
GtkListStore *store;
GtkWidget* wid;
GtkTreeIter* iter;
};
struct retObj create_and_fill_model (void) {
GtkListStore *store;
GtkTreeIter iter;
store =
gtk_list_store_new (3, G_TYPE_INT, G_TYPE_INT,
G_TYPE_INT);
for (int a = 0; a < 4; a++) {
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
0, 1,
1, 2,
2, 3,
-1);
}
struct retObj tempret;
tempret.store = store;
tempret.iter = &iter;
return tempret;
}
struct retObj create_view_and_model (void) {
struct retObj ro;
GtkCellRenderer *renderer;
GtkTreeModel *model;
GtkWidget *view;
view = gtk_tree_view_new ();
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
-1,
"First column",
renderer,
"text", 0, NULL);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
-1,
"Second column",
renderer,
"text", 1, NULL);
ro = create_and_fill_model();
model = GTK_TREE_MODEL (ro.store);
gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
g_object_unref (model);
ro.wid = view;
return ro;
}
void addrow(struct retObj abc) {
GtkTreeIter iter;
gtk_list_store_append (abc.store, &iter);
gtk_list_store_set (abc.store, &iter,
0, -1,
1, -2,
2, 3,
-1);
}
int main (int argc, char **argv) {
GtkWidget *window;
GtkWidget *view;
GtkWidget *vbox;
GtkWidget *sw;
GtkListStore *st;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (window), 15);
g_signal_connect (window, "delete_event", gtk_main_quit, NULL);
struct retObj rroo;
rroo = create_view_and_model ();
view = rroo.wid;
st = rroo.store;
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 15);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_box_pack_start (GTK_BOX (vbox),
gtk_label_new ("Practice"),
FALSE, FALSE, 0);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (sw), view);
gtk_window_set_default_size (GTK_WINDOW (window), 480, 620);
gtk_widget_show_all (window);
int cont = 1;
while(cont != 0) {
printf("Enter 1 to add row\nEnter 0 to stop\n");
scanf("%d", &cont);
addrow(rroo);
}
gtk_main ();
return 0;
}
Here the function "create_and_fill_model()" creates an intial GtkTreeView window with 4 rows, of 3 columns each, whereas the function "addRow()" adds more rows to the original GtkTreeView. In the main() I am running a loop and taking user input, and while the input is 1, I am calling addRow() function. Now the addRow function is called as many times as a positive input is given, but the problem is that GUI only pops up in the end.
What I want is the GUI to pop up as soon as the program is executed, and on every positive input, when the addRow() function is called, the GUI should keep on updating. I have been told to use "g_idle_add()" for it, but I am really confused to do it exactly in this program.