Прокручиваемый макет в GTK3 - PullRequest
0 голосов
/ 15 октября 2019

Я пытаюсь написать C-программу с использованием GTK (точнее, GTK 3) (до сих пор мой опыт в основном использовал ObjC, Visual Studio и т. Д., Но кросс-платформенный FTW!)

Мне нужно иметь прокручиваемую таблицу, поэтому я играл с некоторыми примерами кода, которые я нашел в сети. Единственный табличный код, который я смог найти до сих пор, увеличивает окно и выталкивает любые другие элементы вниз по экрану при добавлении строк. Мне нужно, чтобы таблица была фиксированного размера и прокручивалась (конечно, оставляя видимой строку заголовка).

Это то, что я получил до сих пор:

#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 и в основном многократные итерации в попытке заставить его работать.

В настоящий момент таблица очень кратко отображается перед исчезновением (это интересное поведение началось только тогда, когда я попытался превратить его вполе прокрутки).

Обратите внимание, я хочу, чтобы прокручивалась только таблица, а не все окно. В идеальном мире таблица будет иметь ширину окна (или компоновку, которая его содержит), но ограничена n пикселями в высоту, с полосой прокрутки, если высота превышает этот предел.

Я простой пареньтем не менее, поэтому я также хочу, чтобы любое решение было простым - чтобы я мог обернуть его в мозг!

Есть идеи?

1 Ответ

1 голос
/ 15 октября 2019

Вы используете 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;
}
...