如何理解 Gtk+ 属性并使 GtkGrid 扩展到可用区域?
Posted
技术标签:
【中文标题】如何理解 Gtk+ 属性并使 GtkGrid 扩展到可用区域?【英文标题】:How to understand Gtk+ properties and make GtkGrid expand to available area? 【发布时间】:2013-09-02 01:30:05 【问题描述】:我在 Gtk+ 教程和参考资料中磕磕绊绊,试图了解如何完成一个体面的布局。文档说您应该使用 GtkGrid
而不是已弃用的 Box/HBox/VBox,但我无法让 GtkGrid
扩展到完整的窗口大小。使用gtk_widget_set_hexpand
对GtkGrid
完全没有影响。
This answer suggests“查看expand
属性”但我找不到有关什么这些属性实际上是以及如何设置它们的信息(我只是假设每个属性总是有一个 getter/setter 对,但在这种情况下没有 gtk_widget_set_expand
函数。
我错过了什么?
更新:
设置扩展属性仍然不起作用 - 按钮“粘”在窗口的左上角。这是代码:
static void initializeGui()
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Blabla");
gtk_window_set_default_size(GTK_WINDOW(window), 800, 500);
gtk_window_set_hide_titlebar_when_maximized(GTK_WINDOW(window), TRUE);
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
g_signal_connect(window, "delete-event", G_CALLBACK(onWindowDelete), NULL);
g_signal_connect(window, "destroy", G_CALLBACK(onWindowDestroy), NULL);
GtkWidget *mainbox = gtk_grid_new();
g_object_set(G_OBJECT(mainbox), "expand", TRUE, NULL);
GtkWidget *button = gtk_button_new_with_label("Short button");
g_signal_connect(button, "clicked", G_CALLBACK(onButtonClick), NULL);
gtk_grid_attach(GTK_GRID(mainbox), button, 0, 0, 1, 1);
button = gtk_button_new_with_label("Very very long button");
gtk_grid_attach(GTK_GRID(mainbox), button, 1, 0, 1, 1);
button = gtk_button_new_with_label("Tiny btn");
gtk_widget_set_halign(button, GTK_ALIGN_END);
gtk_grid_attach(GTK_GRID(mainbox), button, 1, 1, 1, 1);
gtk_container_add(GTK_CONTAINER(window), mainbox);
gtk_widget_show_all(window);
【问题讨论】:
【参考方案1】:很难说您缺少什么,因为您没有包含示例代码。除了 hexpand 和 vexpand 之外,了解 halign 和 valign 属性可能会有所帮助——尽管您所描述的内容应该可以通过展开来实现。
您还应该了解处理此问题的旧方法,即容器“子属性”(例如,请参阅 gtk_box_pack_start()
以了解它们是如何使用的)。这可能会让人感到困惑,因为有 expand child property 和 hexpand/vexpand widget properties... 不过两者都有明确的记录。
文档说您应该使用 GtkGrid 而不是已弃用的 盒子/HBox/VBox
这并不是关于 GtkBox 的全部内容:它没有被弃用,可以在您需要列或行容器时使用。也就是说,单行/列 GtkGrid 做的事情完全相同,在我看来,它有一个更干净的 api...
我找不到有关此属性实际是什么以及如何设置它们的信息
文档通常会解释属性是什么:https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget--expand。如果没有设置器(或者你想一次设置多个属性)你可以使用g_object_set
:
g_object_set (widget, "expand", TRUE, NULL);
更新:
从添加的代码看来,GtkGrid 实际上是按照您的需要扩展的(但这无法通过视觉确认)。另一方面,按钮未设置为展开。如果你这样做,我相信你甚至可以删除 GtkGrids 扩展,因为该属性应该“向上传播”容器链)。
你没有提到你想让按钮做什么,但你可能想使用 halign/valign 进行不同的对齐方式(填充/居中/等)。
更新 2:
根据您真正想要实现的目标的描述,以下更改似乎符合您的要求。左侧的按钮设置为展开并左对齐,其他按钮右对齐:因此所有按钮都紧贴窗口的两侧并具有最小宽度。
#include <gtk/gtk.h>
int main( int argc, char *argv[])
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 800, 500);
GtkWidget *mainbox = gtk_grid_new();
GtkWidget *button = gtk_button_new_with_label("Short button");
gtk_widget_set_hexpand (button, TRUE);
gtk_widget_set_halign (button, GTK_ALIGN_START);
gtk_grid_attach(GTK_GRID(mainbox), button, 0, 0, 1, 1);
button = gtk_button_new_with_label("Very very long button");
gtk_widget_set_halign(button, GTK_ALIGN_END);
gtk_grid_attach(GTK_GRID(mainbox), button, 1, 0, 1, 1);
button = gtk_button_new_with_label("Tiny btn");
gtk_widget_set_halign(button, GTK_ALIGN_END);
gtk_grid_attach(GTK_GRID(mainbox), button, 1, 1, 1, 1);
gtk_container_add(GTK_CONTAINER(window), mainbox);
gtk_widget_show_all(window);
gtk_main();
return 0;
【讨论】:
GtkBox 还没有被弃用,但文档声明你不应该将它用于“面向未来”的代码。没有意识到属性是 GObject 的一部分,而不是 Gtk - 我很惭愧 :) 出于某种原因,它仍然不适用于扩展属性集。我添加了代码,你可以看看吗? 您对未来的校对有意见。我已经更新了答案,希望你能掌握其中的窍门——GTK 盒子模型有点古怪(而且遗留的 cruft 无济于事),但当你“明白”时它非常强大。 是的,如果您展开按钮,更改将传播到容器。但是,我会对第 0 列中的按钮触摸左侧窗口侧,第 1 列中的按钮触摸右侧窗口侧的解决方案感兴趣,并且所有按钮仅占用所需的空间,仅此而已。如您所见,我已经在代码中尝试了按钮的 halign 属性,遗憾的是没有达到预期的效果。 所以我尝试了您的代码,据我所知, hexpand + halign 似乎完全符合您的描述(请参阅更新的答案)...如果还有什么我遗漏的,请告诉我。 “GtkAlignment 在 3.14 中已被弃用,不应在新编写的代码中使用。可以通过在子部件上使用“halign”、“valign”和“margin”属性来实现所需的效果。” link.【参考方案2】:下面的代码是显示网格和展开属性的 Vala 代码:
m_form_detail_grid = new Gtk.Grid();
m_form_detail_grid.row_spacing = 10;
m_form_detail_grid.column_spacing = 5;
// m_form_detail_grid.column_homogeneous = true;
m_form_detail_grid.expand = true;
m_form_detail_grid.margin = 30;
m_form_detail_grid.orientation = Gtk.Orientation.VERTICAL;
for (int index = 0; index < column_count; index++)
column_title = this.m_data_model.get_column_title(index).replace ("_", "__");
column_label = new Gtk.Label(column_title);
column_label.hexpand = false;
column_label.halign = Gtk.Align.END;
column_widget = new Gtk.Entry();
column_widget.editable = true;
column_widget.hexpand = true;
column_widget.halign = Gtk.Align.FILL;
m_form_detail_grid.attach (column_label, 0, index, 1, 1);
m_form_detail_grid.attach (column_widget, 1, index, 7, 1);
【讨论】:
以上是关于如何理解 Gtk+ 属性并使 GtkGrid 扩展到可用区域?的主要内容,如果未能解决你的问题,请参考以下文章