【c/python】GtkGrid

news2025/1/9 4:38:15

一、GtkGrid

GtkGrid 是 GTK (GIMP Toolkit) 中的一个基础容器构件(widget),它可以用来安排其他构件在一个灵活的多行多列的网格中。每个加入网格的构件都可以占据一个或多个行和列。由于 GtkGrid 提供了在二维空间中安排构件的方式,它被广泛用于创建复杂的用户界面。

在 GTK 3 和 GTK 4 中,`GtkGrid` 的使用方法有所不同,下面将给出一个简单的例程,展示如何在 GTK 3 中使用 GtkGrid。如果 GTK 版本是 GTK 4,则代码中的某些部分可能需要做出调整。

首先,确保已经安装了 GTK 开发库。在大多数基于 Debian 的系统上(如 Ubuntu),可以使用以下命令安装:

sudo apt-get install libgtk-3-dev

以下是一个简单的 GTK 3 程序,该程序创建了一个包含几个按钮的窗口,并使用 GtkGrid 来组织这些按钮:

#include <gtk/gtk.h>

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

    GtkWidget *window;
    GtkWidget *grid;
    GtkWidget *button;

    // 创建一个新的窗口
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "GtkGrid Example");
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    // 创建一个 GtkGrid
    grid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(window), grid);

    // 创建并添加第一个按钮
    button = gtk_button_new_with_label("Button 1");
    gtk_grid_attach(GTK_GRID(grid), button, 0, 0, 1, 1); // 放置在网格的 (0, 0)

    // 创建并添加第二个按钮
    button = gtk_button_new_with_label("Button 2");
    gtk_grid_attach(GTK_GRID(grid), button, 1, 0, 1, 1); // 放置在网格的 (1, 0)

    // 创建并添加第三个按钮
    button = gtk_button_new_with_label("Button 3");
    // 放置在网格的 (1, 1),并跨越2列
    gtk_grid_attach(GTK_GRID(grid), button, 0, 1, 2, 1);

    // 显示所有的构件
    gtk_widget_show_all(window);

    // 进入 GTK 主循环
    gtk_main();

    return 0;
}

这段代码完成以下任务:

1. 初始化 GTK 库。
2. 创建一个新的 GTK 窗口,并为其设置标题和默认大小。
3. 连接窗口的 "destroy" 信号到 gtk_main_quit 函数,它将允许在关闭窗口时退出 GTK 主循环。
4. 创建 GtkGrid 并将其添加到窗口中。
5. 创建三个按钮构件,并使用 gtk_grid_attach() 函数将它们放置在合适的位置和跨度中。其中 gtk_grid_attach() 函数的参数分别代表网格、要放置的构件、构件的左上角列和行的坐标,以及构件横向和纵向上占据的列和行数。
6. 通过 gtk_widget_show_all() 展示窗口和其中的所有构件。

7. 进入 GTK 的主循环。

为了编译这个程序,可能需要使用 pkg-config 来获取正确的 GTK 编译和链接标志。一个典型的编译命令如下:

gcc `pkg-config --cflags gtk+-3.0` -o gtk_grid_example gtk_grid_example.c `pkg-config --libs gtk+-3.0`

这将产生一个可执行文件 gtk_grid_example。运行该文件将弹出一个带有布局按钮的窗口。请注意,上面的代码示例仅适用于 GTK 3;GTK 4 中的相应函数可能会有所不同。

二、GtkGrid和GtkBox有什么不同?

​​​​​​​GtkGrid 和 GtkBox 都是 GTK 中用于布局的容器构件,但它们各自有不同的特性和用途。

GtkBox

GtkBox 是一个一维的布局容器,可以按照水平或垂直方向排列子构件。
- 子构件会按照它们被添加的顺序依次排列。
- 可以为子构件设置填充和扩展属性,但所有的子构件仅能在一个维度(水平或垂直)上进行布局。

- 适合用于简单的布局,如果需要在两个维度上进行布局,则可能需要嵌套使用多个 GtkBox 构件。

例如,一个垂直的 GtkBox 可能包含几个水平的 GtkBox 来实现一个网格布局,但这样会使结构变得更为复杂。

GtkGrid

GtkGrid 是一个二维的布局容器,它提供了一种在多行多列网格中排列子构件的方式。
- 子构件可以占据多行或多列,为设计复杂的布局提供了更大的灵活性。
GtkGrid 提供更精细的对齐和分布控制,这使得它更适合实现复杂的用户界面设计。

- 使用 GtkGrid 可以避免嵌套容器的需要,以更直接的方式创建布局。

简言之,`GtkGrid` 提供了比 GtkBox 更复杂和灵活的布局方案。对于需要在两个维度上对构件进行布局的情况,特别是当需要构件跨行或列展示时,`GtkGrid` 是更好的选择。然而,如果只需要在一维上对构件进行简单的排列,那么 GtkBox 是一个更简单和轻量级的选择。

从 GTK 3 开始,`GtkGrid` 通常被推荐用来替代 GtkBox 进行复杂布局的设计,因为它可以减少需要嵌套使用容器的情况,从而使界面的层次结构更加清晰。

三、GtkGrid的python例程

要在Python中使用`GtkGrid`,需要先确保有一个可用的Python GTK+ 3绑定,通常称为`PyGObject`。在大多数基于Debian的系统上,可以通过以下命令来安装:

sudo apt-get install python3-gi python3-gi-cairo gir1.2-gtk-3.0

下面是一个简单的Python例程,这个例程使用`GtkGrid`来创建一个窗口,其中包含一个按钮位于窗口的右下角:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class GridWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Grid Example")

        grid = Gtk.Grid()
        self.add(grid)

        # 创建一个按钮,并设置适当的边距
        button = Gtk.Button(label="Right Bottom Button")
        # 这里设置边距是为了让按钮远离窗口的边界
        button.set_margin_right(10)
        button.set_margin_bottom(10)
        
        # 将按钮添加至网格的右下角
        # Gtk.Grid.attach_next_to() 方法可以用于放置构件,
        # 但我们这里使用 Gtk.Grid.attach() 是因为我们希望按钮在右下角,占据一个单元格
        # 我们使用负的左边距和顶边距来确保按钮在右下角
        grid.attach(button, 0, 0, 1, 1)
        grid.set_halign(Gtk.Align.END)
        grid.set_valign(Gtk.Align.END)

        # 连接窗口的 "destroy" 事件到 Gtk.main_quit 函数
        self.connect("destroy", Gtk.main_quit)

# 创建一个 GridWindow 的实例,并显示它
window = GridWindow()
window.show_all()
Gtk.main()

以上脚本主要做了以下几件事情:

1. 导入 gi.repository 的 GTK+ 3 组件。
2. 定义一个`GridWindow`类,该类继承自 Gtk.Window 类,并在初始化方法中设置窗口和布局。
3. 创建一个 Gtk.Grid 容器和一个按钮构件。
4. 将按钮置于网格的右下角。借助 grid 的 set_halign 和 set_valign 方法,并设置为 Gtk.Align.END,可以保证网格本身对齐到窗口的右下角。

5. 最后,连接了窗口的 "destroy" 事件到 GTK 的主循环退出函数 Gtk.main_quit,并显示了所有构件。

请注意`set_margin_right`和`set_margin_bottom`可能在系统的PyGObject版本中不起作用(这取决于PyGObject的版本)。如果是这种情况,应当使用`set_margin_end`和`set_margin_bottom`方法替代。

要运行此脚本,请将其保存为一个 .py 文件,并使用Python 3运行它:

python3 your_script.py

执行脚本后,会出现一个窗口,窗口的右下角会有一个按钮。

这段代码,运行时可能提示:

gtk_grid_example.py:16: DeprecationWarning: Gtk.Widget.set_margin_right is deprecated
  button.set_margin_right(10)

GTK 所发出的 DeprecationWarning 表明,正在使用的方法已经被废弃,也就是说,在未来的 GTK 版本中,此方法可能会被移除。这种警告常常出现当库的开发者希望开发者迁移到新的方法或接口时。

对于遇到的具体情况,`Gtk.Widget.set_margin_right` 方法在 GTK 3.12 版本中被标记为废弃,并且在 GTK 3.14 版本中被移除。官方文档建议使用 set_margin_end 方法来替换 set_margin_right,因为后者不再是国际化的好选择。新的方法是基于文本方向敏感的边距设定,其中 "end" 表示在水平方向上的边距,当语言是从右到左的文字时,就变成了右边距,而对于从左到右的语言,则是左边距。

所有关于边距的方法都有四个替代选项:

set_margin_start: 设置开始边(左边或右边,取决于文本方向)的边距。
set_margin_end: 设置结束边(右边或左边,取决于文本方向)的边距。
set_margin_top: 设置顶部的边距。

set_margin_bottom: 设置底部的边距。

在代码中,可以这样更新来消除 DeprecationWarning 警告:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class GridWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Grid Example")

        grid = Gtk.Grid()
        self.add(grid)

        button = Gtk.Button(label="Right Bottom Button")
        button.set_margin_end(10)  # 使用 set_margin_end 替代 set_margin_right
        button.set_margin_bottom(10)

        grid.attach(button, 0, 0, 1, 1)
        grid.set_halign(Gtk.Align.END)
        grid.set_valign(Gtk.Align.END)

        self.connect("destroy", Gtk.main_quit)

window = GridWindow()
window.show_all()
Gtk.main()

请注意,更新代码后,对于 set_margin_end 方法,它设置的将是按钮的结束边的边距,而不是始终是右边的边距,它会根据应用内容的语言方向发生变化。如果应用面向国际用户,这是一个有利的修改,因为它将遵循用户的语言习惯(LTR或RTL)。如果确定只需要设置固定的边距(比如右边距),需要确保界面不会根据语言方向改变,或者使用其他方法来保证边距适用于界面设计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1434275.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kvm qemu 优化 windows 虚拟机速度

主要优化磁盘 io 和网络 io 都选为 virtio windows 驱动下载 https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.185-2/virtio-win-0.1.185.iso I also had incredibly slow performance with my virtual HDD. The followin…

【LeetCode】刷题总结 - 15. 三数之和

15. 三数之和 | LeetCode 思路 首先对 nums 进行排序&#xff0c;然后设置三个指针&#xff1a;left、mid、right&#xff1a; left 从最左边开始&#xff0c;依次向后遍历每次固定住 left 后&#xff0c;就化为一个 2sum 问题&#xff1a; mid left 1&#xff0c;right …

基于Java (spring-boot)的实验室管理系统

一、项目介绍 基于Java (spring-boot)的交通管理系统功能&#xff1a;注册登录、个人信息管理、驾驶证业务类型管理、机动车业务类型管理、新闻类型管理、违法处理业务类型管理、驾驶证业务管理、机动车业务管理、新闻管理、违法处理业务管理、用户管理。 二、作品包含 ​ 三、…

[软件工具]文档页数统计工具软件pdf统计页数word统计页数ppt统计页数图文打印店快速报价工具

文档页数统计工具软件——打印方面好帮手 在信息化时代&#xff0c;文档已成为我们工作、学习、生活中不可或缺的一部分。无论是学术论文、商业报告&#xff0c;还是个人日记&#xff0c;都需要我们对其进行有效的管理。而在这个过程中&#xff0c;文档页数统计工具软件就显得…

[office] 教你实现Excel中工作表重命名的诀窍 #知识分享#职场发展#其他

教你实现Excel中工作表重命名的诀窍 在Excel中要实现工作表的重命名其实不是难事&#xff0c;重在你要掌握技巧。一些初学者&#xff0c;可能还不是特别的懂。今天&#xff0c;小编就要一步步来教一下大家了。有两种方法&#xff0c;大家学好了。 方法一、打开excel表格&#x…

111.乐理基础-五线谱-五线谱的节奏型、打拍子

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;110.乐理基础-五线谱-五线谱的速度-CSDN博客 首先必须先看 打拍子 这些东西 简谱里的节奏型总结图&#xff1a; 换成五线谱的节奏型&#xff1a;简谱里会把两个八分音符用根横线连起来&#xff0c;所以五线谱里也…

C#中dll引用常见错误

当你在使用C#开发程序时&#xff0c;经常会遇到需要引用外部的dll文件来扩展程序的功能或者使用一些第三方库。然而&#xff0c;在引用这些dll文件的过程中&#xff0c;有时候会遇到一些问题&#xff0c;比如上面提到的错误信息&#xff1a;“未能加载文件或程序集“System.Run…

Java实现婚恋交友网站 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 会员管理模块2.3 新闻管理模块2.4 相亲大会管理模块2.5 留言管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 会员信息表3.2.2 新闻表3.2.3 相亲大会表3.2.4 留言表 四、系统展示五、核心代码5.…

如何使用MCSM搭建我的世界Java版服务器并实现远程联机游戏

文章目录 1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 本教程主要介…

寒假作业-day4

单向链表增删 #include <myhead.h> typedef struct a {int date;struct a *next; }aa; //创建节点 aa *Creat() {aa *s(aa*)malloc(sizeof(aa));s->date0;s->nextNULL;return s; } //头插 aa *insert(aa *head,int num) {aa *sCreat();s->datenum;if(NULLhead)…

[C语言] 指针详解(1)

一. 指针 利用指针,可以找到相对应内存地址(唯一的一段编号),从而定位数据. (通俗来说,指针就是变量,用来存放内存单元的地址) 保存一段 16进制的 地址编号 二、指针类型/变量: 类型: 基础类型* 如: int* char*指针变量: int* pa pa就为指针变…

2.5学习总结

2.5 1.传纸条 2.装箱问题 3.开心的金明 4.传球游戏 5.修改数组 6.对局匹配 7.刷题统计 传纸条https://www.luogu.com.cn/problem/P1006 题目描述 小渊和小轩是好朋友也是同班同学&#xff0c;他们在一起总有谈不完的话题。一次素质拓展活动中&#xff0c;班上同学安排坐成一…

【已解决】青龙面板依赖安装失败原因

青龙面板必须安装依赖&#xff0c;才可以执行脚本&#xff0c;这是不争的事实。 如果脚本跑不起来&#xff0c;就去看看依赖吧。 NodeJs 依赖如下 axios request canvas cheerio js-base64 dotenv magic tough-cookie ws7.4.3 require requests date-fns ts-md5 typescript j…

Office恢复旧UI|Office UI问题|Word UI|小喇叭找不到

Office恢复旧UI&#xff5c;Office UI问题&#xff5c;Word UI&#xff5c;小喇叭找不到 问题描述&#xff1a;Office新版本默认新UI&#xff0c;主界面没有小喇叭可以切换到旧UI. 解决方案&#xff1a; 以下述内容新建.txt&#xff0c;保存并改后缀为.reg&#xff0c;双击打开…

从领域外到领域内:LLM在Text-to-SQL任务中的演进之路

导语 本文介绍了ODIS框架&#xff0c;这是一种新颖的Text-to-SQL方法&#xff0c;它结合了领域外示例和合成生成的领域内示例&#xff0c;以提升大型语言模型在In-context Learning中的性能。 标题&#xff1a;Selective Demonstrations for Cross-domain Text-to-SQL会议&am…

Qt设计师中(没有现成的控件):如何添加QToolBar工具栏

1、在QtCreator设计师界面中,在MainWindow上右键,有“添加工具栏”菜单项 2、但只有在MainWindow上右键才有&#xff0c;在其它控件上方点击则没有&#xff0c;那么怎么在对话框上添加呢&#xff1f; 可以添加一个QWidget&#xff0c;然后手动在ui文件里把class改为QToolBar就…

ONLYOFFICE 桌面编辑器8.0上新!六大更新内容等你来用!

各位铁铁&#xff0c;相信你们对ONLYOFFICE都不陌生了&#xff0c;那么今天咱们具体来看看ONLYOFFICE桌面编辑器8.0的上的六大新内容吧~ 更新一&#xff1a;可填写的PDF表单 8.0版本中最引人瞩目的改进之一&#xff0c;是具备创建高度复杂的PDF表单的能力&#xff0c;并允许用…

CSS的Day05(浮动+flex布局)

跟着黑马程序员的课&#xff0c;稍稍对CSS的了解 常见的显示模式&#xff1a;行内、块级、行内块 在HTML中&#xff0c;标准流也称为文档流或普通流&#xff0c;是指元素按照其在HTML文档中的出现顺序依次排列的方式。在标准流中&#xff0c;元素会自动占据父容器的空间&#…

什么是TCP三次握手、四次挥手?

&#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是小徐&#x1f947;☁️博客首页&#xff1a;CSDN主页小徐的博客&#x1f304;每日一句&#xff1a;好学而不勤非真好学者 &#x1f4dc; 欢迎大家关注&#xff01; ❤️ 1、三次握手 你(客户端)给一个朋友(服务器)打电…

前端面试题-网络部分-http和其他协议之间的区别-ajax请求的步骤-XSS,CSRF-http的加密过程- 浏览器缓存

前端面试题-网络部分-http和其他协议之间的区别-ajax请求的步骤-XSS,CSRF-如果ajax请求-http的加密过程 http和其他协议之间的区别http和tcp之间的区别http和websocket协议有什么区别 Ajax请求的步骤什么是XSS&#xff0c;CSRF攻击https加密的过程浏览器缓存 http和其他协议之间…