Frage

I have written a small test application which generates a GUI as below: enter image description here

I am very much new to gtk programming.In this small GUI, there is a treeview, which when I try expand it, it is crossing the viewable window size.I just want to add a scrollbar(vertical) to this window which shows the treeview and I want to catch the event of that scroll bar whenever it is moved up or down(in steps). Can anybody help me how to add this functionality to the my current small GUI. Unfortunately i did not find any good material online regarding this which provoked me to ask this question.

I guess this should be an easy task for a genuine gtk programmer.

Below is the code for the same:

#include <gtk/gtk.h>

enum
{
  COLUMN = 0,
  NUM_COLS
} ;

void  on_changed(GtkWidget *widget, gpointer statusbar)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
  char *value;


  if (gtk_tree_selection_get_selected(
      GTK_TREE_SELECTION(widget), &model, &iter)) {

    gtk_tree_model_get(model, &iter, COLUMN, &value,  -1);
    gtk_statusbar_push(GTK_STATUSBAR(statusbar), gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), value), value);
    g_free(value);
  }
}


static GtkTreeModel *
create_and_fill_model (void)
{
  GtkTreeStore *treestore;
  GtkTreeIter toplevel, child;

  treestore = gtk_tree_store_new(NUM_COLS,
                  G_TYPE_STRING);

  gtk_tree_store_append(treestore, &toplevel, NULL);
  gtk_tree_store_set(treestore, &toplevel, COLUMN, "Scripting languages", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "Python", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "Perl", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "PHP", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "KSH", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "CSH", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "AWK", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "SED", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "ACK", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "python", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "BASH", -1);

  gtk_tree_store_append(treestore, &toplevel, NULL);
  gtk_tree_store_set(treestore, &toplevel, COLUMN, "Compiled languages", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "C", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "C++", -1);

  gtk_tree_store_append(treestore, &child, &toplevel);
  gtk_tree_store_set(treestore, &child, COLUMN, "Java", -1);

  return GTK_TREE_MODEL(treestore);
}


static GtkWidget *create_view_and_model (void)
{
  GtkTreeViewColumn *col;
  GtkCellRenderer *renderer;
  GtkWidget *view;
  GtkTreeModel *model;

  view = gtk_tree_view_new();

  col = gtk_tree_view_column_new();
  gtk_tree_view_column_set_title(col, "Programming languages");
  gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);

  renderer = gtk_cell_renderer_text_new();
  gtk_tree_view_column_pack_start(col, renderer, TRUE);
  gtk_tree_view_column_add_attribute(col, renderer, "text", COLUMN);

  model = create_and_fill_model();
  gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
  g_object_unref(model);

  return view;
}




int main (int argc, char **argv)
{
  GtkWidget *window;
  GtkWidget *view;
  GtkTreeSelection *selection;
  GtkWidget *vbox;
  GtkWidget *statusbar;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_title(GTK_WINDOW(window), "Tree View");
  gtk_widget_set_size_request (window, 350, 300);

  vbox = gtk_vbox_new(FALSE, 2);
  gtk_container_add(GTK_CONTAINER(window), vbox);

  view = create_view_and_model();
  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));

  gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 1);

  statusbar = gtk_statusbar_new();
  gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, TRUE, 1);

  g_signal_connect(selection, "changed", G_CALLBACK(on_changed), statusbar);
  g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
  gtk_widget_show_all(window);
  gtk_main();

  return 0;
}

Below is the makefile I am using

GTK_INCLUDE = -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/openwin/include -I/usr/sfw/include -I/usr/sfw/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
GTK_LIB = -L/usr/lib
X11_LIB = -L/usr/lib
CC = gcc -g -Wall
CFLAGS = $(GTK_INCLUDE)
LDFLAGS = $(GTK_LIB) $(X11_LIB) -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lmlib -lpangoxft-1.0 -lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0

OBJS = testgtk.o

helloworld:     $(OBJS)
        $(CC) $(GTK_LIB) $(X11_LIB) $(OBJS) -o helloworld $(LDFLAGS)

clean:
        rm -f *.o *~ helloworld

EDIT: Following unwind suggestion I have tried catching the vertical adjustment with the below code:

  adj = (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
  scwin = gtk_scrolled_window_new(NULL, adj);
  gtk_container_add(GTK_CONTAINER(scwin), view);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scwin), GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);
  gtk_box_pack_start(GTK_BOX(vbox), scwin, TRUE, TRUE, 1);

  statusbar = gtk_statusbar_new();
  gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, TRUE, 1);
  gtk_signal_connect(GTK_OBJECT(scwin), "changed",G_CALLBACK(my_function),NULL);

But unfortunately it doesnt work :( . my_funtion is not getting called. Added to that i am getting an assertion failure:

(helloworld:6260): GLib-GObject-CRITICAL **: file gsignal.c: line 1543: assertion `signal_id > 0' failed

Could anybody please help here.

  • EDIT:

I added a gtk_vscrollbar_new and attached it to the adjustment created and handled the signal using the using the scrollbar widget. and now i can hadle a scrollbar movement.

War es hilfreich?

Lösung

Adding a scrollbar is easy, what you do is wrap your treeview in a GtkScrolledWindow widget. The scrolled window takes care of making its child scrollable.

To do this, replace your code that adds the "naked" treeview:

gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 1);

with:

GtkWidget *scwin = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(scwin), view);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scwin), GTK_POLICY_AUTOMATIC,
                               GTK_POLICY_ALWAYS);
gtk_box_pack_start(GTK_BOX(vbox), scwin, TRUE, TRUE, 1);

The call to gtk_scrolled_window_set_policy() makes sure the vertical bar is always shown (but not the horizontal, unless needed to make all content visible).

You typically don't need to care about when the scrollbars are manipulated; the data is already there in the tree model, so there's nothing to do (scrolling is a "read only" operation, typically).

You can, if you really want to, hook up to the scrolled window's scrollbar(s)'s adjustment using the value-changed signal. A GtkAdjustment is what a scrollbar makes visible.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top