在gtk中添加一个垂直滚动条并捕获其事件

时间:2013-06-11 09:12:09

标签: c gtk gtk2

我编写了一个小型测试应用程序,它生成如下GUI: enter image description here

我是gtk编程的新手。在这个小的GUI中,有一个树视图,当我尝试展开它时, 它正在穿过可视窗口大小。我只想在此窗口中添加滚动条(垂直),以显示树视图 并且我想要在向上或向下移动(步骤)时捕获该滚动条的事件。有谁能够帮我 如何将此功能添加到我当前的小GUI。不幸的是,我没有在网上找到任何关于此的好材料 这让我想问这个问题。

我想这对于一个真正的gtk程序员来说应该是一件容易的事。

以下是相同的代码:

#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;
}

以下是我正在使用的makefile

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

修改: 在展开建议后,我尝试使用以下代码捕获垂直调整:

  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);

但不幸的是它不起作用:(。my_funtion没有被调用。 除此之外,我得到一个断言失败:

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

有人可以帮忙吗。

  • 修改

我添加了一个gtk_vscrollbar_new并将其附加到创建的调整并使用滚动条小部件处理信号。现在我可以进行滚动条运动了。

1 个答案:

答案 0 :(得分:4)

添加滚动条很简单,您可以将树视图包装在GtkScrolledWindow小部件中。滚动窗口负责使其子项可滚动。

为此,请替换添加“裸”树视图的代码:

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

使用:

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);

gtk_scrolled_window_set_policy()的调用可确保始终显示垂直条(但不显示水平条,除非需要使所有内容可见)。

您通常无需关心何时操纵滚动条;数据已存在于树模型中,因此无需执行任何操作(滚动是“只读”操作,通常)。

如果您真的想要,可以使用value-changed信号连接到滚动窗口的滚动条调整。 GtkAdjustment是滚动条可见的内容。