1

我编写了一个小型测试应用程序,它生成如下 GUI: 在此处输入图像描述

我对 gtk 编程非常陌生。在这个小 GUI 中,有一个树视图,当我尝试扩展它时,它超出了可视窗口大小。我只想在这个窗口中添加一个滚动条(垂直),它显示treeview,我想在滚动条向上或向下移动时(分步)捕捉它的事件。任何人都可以帮助我如何将此功能添加到我当前的小型 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 并将其附加到使用滚动条小部件创建和处理信号的调整中。现在我可以进行滚动条移动了。

4

1 回答 1

5

添加滚动条很容易,您所做的就是将树视图包装在一个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信号连接到滚动窗口的滚动条的调整。AGtkAdjustment是滚动条显示的内容。

于 2013-06-11T09:29:50.993 回答