GTK3 中的可滚动布局
Scrollable layout in GTK3
我正在尝试使用 GTK(准确地说是 GTK 3)编写 C 程序(到目前为止,我的经验主要是使用 ObjC、Visual Studio 等等,但跨平台 FTW !)
我需要一个可滚动的 table,所以我一直在研究我在网上找到的一些示例代码。到目前为止,我能够找到的唯一 table 代码会增加 window,并在添加行时将任何其他元素向下推到屏幕下方。我需要 table 为固定大小并滚动(当然,使 header 行可见)。
这是我目前得到的:
#include <gtk/gtk.h>
enum {
FILE_NAME,
FILE_OFFSET,
FILE_SIZE,
FILE_DESCRIPTION, /* Not used by the view, maybe used elsewhere */
COLOR, /* Just to show how the model can affect the view */
N_COLUMNS
};
void add_row (GtkWidget *widget, gpointer data) {
gtk_list_store_insert_with_values(data, NULL, -1,
COLOR, "blue",
-1);
}
void destroy (GtkWidget *widget,gpointer data) {
gtk_main_quit ();
}
gint main(gint argc, gchar **argv)
{
GtkListStore* model;
GtkWidget* view;
GtkTreeViewColumn* column;
gtk_init(&argc, &argv);
/* MODEL */
model = gtk_list_store_new(N_COLUMNS,
G_TYPE_STRING, /* FILE_NAME */
G_TYPE_UINT, /* FILE_OFFSET */
G_TYPE_UINT, /* FILE_SIZE */
G_TYPE_STRING, /* FILE_DESCRIPTION */
G_TYPE_STRING /* COLOR */
);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "test name",
FILE_OFFSET, 0,
FILE_SIZE, 10,
-1);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "Dummy",
FILE_OFFSET, 123,
COLOR, "black",
-1);
/* VIEW */
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
g_object_unref(model);
column = gtk_tree_view_column_new_with_attributes("Name",
gtk_cell_renderer_text_new(),
"text", FILE_NAME,
"background", COLOR,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Offset",
gtk_cell_renderer_spin_new(),
"text", FILE_OFFSET,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Size",
gtk_cell_renderer_text_new(),
"text", FILE_SIZE,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Test App");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
/* Button */
GtkWidget *button;
button = gtk_button_new_with_label ("Add row");
g_signal_connect (button, "clicked", G_CALLBACK(add_row), model);
/* Layoutbox */
GtkWidget *layout_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (window), layout_box);
/* Scrollview */
GtkWidget *scrollview = gtk_layout_new(NULL, NULL);
g_object_set(G_OBJECT(scrollview), "app-paintable", TRUE, NULL);
gtk_widget_add_events (scrollview, GDK_ALL_EVENTS_MASK);
gtk_layout_put (GTK_LAYOUT (scrollview), view, 10, 10);
gtk_widget_set_size_request(view, 300, 200);
gtk_container_add (GTK_CONTAINER (layout_box), scrollview); //view
gtk_widget_show_all(window);
GdkWindow *win = gtk_layout_get_bin_window (GTK_LAYOUT(scrollview));
gdk_window_set_events (win, gdk_window_get_events (win) | GDK_STRUCTURE_MASK);
gtk_main ();
return 0;
}
目前有点乱!抱歉 - 部分原因是我对 GTK 缺乏经验,主要是多次迭代试图让它工作。
目前 table 在消失之前显示的时间非常短(这种有趣的行为只有在我尝试将其变成滚动框时才出现)。
请注意,我只希望 table 滚动 - 而不是整个 window。在一个完美的世界中,table 将是 window(或包含它的布局)的宽度,但限制为 n 像素高,如果高度超过该限制,则带有滚动条。
虽然我是一个简单的人,所以我也希望任何解决方案都简单 - 这样我就可以全神贯注!
有什么想法吗?
您正在使用 GtkLayout,但用于滚动的小部件是 GtkScrolledWindow。
这是修改后的代码:
#include <gtk/gtk.h>
enum {
FILE_NAME,
FILE_OFFSET,
FILE_SIZE,
FILE_DESCRIPTION, /* Not used by the view, maybe used elsewhere */
COLOR, /* Just to show how the model can affect the view */
N_COLUMNS
};
void add_row (GtkWidget *widget, gpointer data) {
gtk_list_store_insert_with_values(data, NULL, -1,
COLOR, "blue",
-1);
}
void destroy (GtkWidget *widget,gpointer data) {
gtk_main_quit ();
}
gint main(gint argc, gchar **argv)
{
GtkListStore* model;
GtkWidget* view;
GtkTreeViewColumn* column;
gtk_init(&argc, &argv);
/* MODEL */
model = gtk_list_store_new(N_COLUMNS,
G_TYPE_STRING, /* FILE_NAME */
G_TYPE_UINT, /* FILE_OFFSET */
G_TYPE_UINT, /* FILE_SIZE */
G_TYPE_STRING, /* FILE_DESCRIPTION */
G_TYPE_STRING /* COLOR */
);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "test name",
FILE_OFFSET, 0,
FILE_SIZE, 10,
-1);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "Dummy",
FILE_OFFSET, 123,
COLOR, "black",
-1);
/* VIEW */
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
g_object_unref(model);
column = gtk_tree_view_column_new_with_attributes("Name",
gtk_cell_renderer_text_new(),
"text", FILE_NAME,
"background", COLOR,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Offset",
gtk_cell_renderer_spin_new(),
"text", FILE_OFFSET,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Size",
gtk_cell_renderer_text_new(),
"text", FILE_SIZE,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Test App");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
/* Button */
GtkWidget *button;
button = gtk_button_new_with_label ("Add row");
g_signal_connect (button, "clicked", G_CALLBACK(add_row), model);
/* Layoutbox */
GtkWidget *layout_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (window), layout_box);
/* Scrollview */
GtkWidget *scrollview = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrollview), view);
/* expand to fill all available space left in the window */
gtk_widget_set_hexpand(scrollview, TRUE);
gtk_widget_set_vexpand(scrollview, TRUE);
gtk_container_add (GTK_CONTAINER (layout_box), scrollview); //view
gtk_container_add (GTK_CONTAINER (layout_box), button);
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
我正在尝试使用 GTK(准确地说是 GTK 3)编写 C 程序(到目前为止,我的经验主要是使用 ObjC、Visual Studio 等等,但跨平台 FTW !)
我需要一个可滚动的 table,所以我一直在研究我在网上找到的一些示例代码。到目前为止,我能够找到的唯一 table 代码会增加 window,并在添加行时将任何其他元素向下推到屏幕下方。我需要 table 为固定大小并滚动(当然,使 header 行可见)。
这是我目前得到的:
#include <gtk/gtk.h>
enum {
FILE_NAME,
FILE_OFFSET,
FILE_SIZE,
FILE_DESCRIPTION, /* Not used by the view, maybe used elsewhere */
COLOR, /* Just to show how the model can affect the view */
N_COLUMNS
};
void add_row (GtkWidget *widget, gpointer data) {
gtk_list_store_insert_with_values(data, NULL, -1,
COLOR, "blue",
-1);
}
void destroy (GtkWidget *widget,gpointer data) {
gtk_main_quit ();
}
gint main(gint argc, gchar **argv)
{
GtkListStore* model;
GtkWidget* view;
GtkTreeViewColumn* column;
gtk_init(&argc, &argv);
/* MODEL */
model = gtk_list_store_new(N_COLUMNS,
G_TYPE_STRING, /* FILE_NAME */
G_TYPE_UINT, /* FILE_OFFSET */
G_TYPE_UINT, /* FILE_SIZE */
G_TYPE_STRING, /* FILE_DESCRIPTION */
G_TYPE_STRING /* COLOR */
);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "test name",
FILE_OFFSET, 0,
FILE_SIZE, 10,
-1);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "Dummy",
FILE_OFFSET, 123,
COLOR, "black",
-1);
/* VIEW */
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
g_object_unref(model);
column = gtk_tree_view_column_new_with_attributes("Name",
gtk_cell_renderer_text_new(),
"text", FILE_NAME,
"background", COLOR,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Offset",
gtk_cell_renderer_spin_new(),
"text", FILE_OFFSET,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Size",
gtk_cell_renderer_text_new(),
"text", FILE_SIZE,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Test App");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
/* Button */
GtkWidget *button;
button = gtk_button_new_with_label ("Add row");
g_signal_connect (button, "clicked", G_CALLBACK(add_row), model);
/* Layoutbox */
GtkWidget *layout_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (window), layout_box);
/* Scrollview */
GtkWidget *scrollview = gtk_layout_new(NULL, NULL);
g_object_set(G_OBJECT(scrollview), "app-paintable", TRUE, NULL);
gtk_widget_add_events (scrollview, GDK_ALL_EVENTS_MASK);
gtk_layout_put (GTK_LAYOUT (scrollview), view, 10, 10);
gtk_widget_set_size_request(view, 300, 200);
gtk_container_add (GTK_CONTAINER (layout_box), scrollview); //view
gtk_widget_show_all(window);
GdkWindow *win = gtk_layout_get_bin_window (GTK_LAYOUT(scrollview));
gdk_window_set_events (win, gdk_window_get_events (win) | GDK_STRUCTURE_MASK);
gtk_main ();
return 0;
}
目前有点乱!抱歉 - 部分原因是我对 GTK 缺乏经验,主要是多次迭代试图让它工作。
目前 table 在消失之前显示的时间非常短(这种有趣的行为只有在我尝试将其变成滚动框时才出现)。
请注意,我只希望 table 滚动 - 而不是整个 window。在一个完美的世界中,table 将是 window(或包含它的布局)的宽度,但限制为 n 像素高,如果高度超过该限制,则带有滚动条。
虽然我是一个简单的人,所以我也希望任何解决方案都简单 - 这样我就可以全神贯注!
有什么想法吗?
您正在使用 GtkLayout,但用于滚动的小部件是 GtkScrolledWindow。
这是修改后的代码:
#include <gtk/gtk.h>
enum {
FILE_NAME,
FILE_OFFSET,
FILE_SIZE,
FILE_DESCRIPTION, /* Not used by the view, maybe used elsewhere */
COLOR, /* Just to show how the model can affect the view */
N_COLUMNS
};
void add_row (GtkWidget *widget, gpointer data) {
gtk_list_store_insert_with_values(data, NULL, -1,
COLOR, "blue",
-1);
}
void destroy (GtkWidget *widget,gpointer data) {
gtk_main_quit ();
}
gint main(gint argc, gchar **argv)
{
GtkListStore* model;
GtkWidget* view;
GtkTreeViewColumn* column;
gtk_init(&argc, &argv);
/* MODEL */
model = gtk_list_store_new(N_COLUMNS,
G_TYPE_STRING, /* FILE_NAME */
G_TYPE_UINT, /* FILE_OFFSET */
G_TYPE_UINT, /* FILE_SIZE */
G_TYPE_STRING, /* FILE_DESCRIPTION */
G_TYPE_STRING /* COLOR */
);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "test name",
FILE_OFFSET, 0,
FILE_SIZE, 10,
-1);
gtk_list_store_insert_with_values(model, NULL, -1,
FILE_NAME, "Dummy",
FILE_OFFSET, 123,
COLOR, "black",
-1);
/* VIEW */
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
g_object_unref(model);
column = gtk_tree_view_column_new_with_attributes("Name",
gtk_cell_renderer_text_new(),
"text", FILE_NAME,
"background", COLOR,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Offset",
gtk_cell_renderer_spin_new(),
"text", FILE_OFFSET,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
column = gtk_tree_view_column_new_with_attributes("Size",
gtk_cell_renderer_text_new(),
"text", FILE_SIZE,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Test App");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
/* Button */
GtkWidget *button;
button = gtk_button_new_with_label ("Add row");
g_signal_connect (button, "clicked", G_CALLBACK(add_row), model);
/* Layoutbox */
GtkWidget *layout_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (window), layout_box);
/* Scrollview */
GtkWidget *scrollview = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrollview), view);
/* expand to fill all available space left in the window */
gtk_widget_set_hexpand(scrollview, TRUE);
gtk_widget_set_vexpand(scrollview, TRUE);
gtk_container_add (GTK_CONTAINER (layout_box), scrollview); //view
gtk_container_add (GTK_CONTAINER (layout_box), button);
gtk_widget_show_all(window);
gtk_main ();
return 0;
}