我编写了一个小型测试应用程序,它生成如下GUI:
我是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并将其附加到创建的调整并使用滚动条小部件处理信号。现在我可以进行滚动条运动了。
答案 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
是滚动条可见的内容。