GTK的布局容器分为两种,一种是single-child容器,继承自Gtk.Bin
,另一种是继承自Gtk.Container
的multiple-child容器。关于这两类Gtk.Bin
和Gtk.Container
的层级结构如下:
与翻译之前的文章不同,我这里便引入glade这个软件,这是一个UI设计器,gtk是声明式UI,与wpf类似是在配置文件中写好的。当然也可以用代码写,但是这样无法做到UI与后台分离。如果是ubuntu的话,使用sudo apt install glade
安装galde即可。
最常用的布局容器是垂直或水平框(Gtk.Box)和网格(Gtk.Grid)
Gtk.Box
打开glade,从“顶层”中选择window添加上,再从“容器”中选择一个box添加到window上,默认box是3条、竖向排列。
保存下,用任一文本编辑器打开刚刚保存的.glade文件就会发现其实这是个xml文件
保存后放到python文件同目录下,使用下面的代码即可加载.glade文件的UI(为了效果,我给.glade文件添加了按钮、文本框和label)
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class Handler:
def onDestroy(self, *args):
Gtk.main_quit()
def onButtonPressed(self, button):
print("Hello World!")
builder = Gtk.Builder()
builder.add_from_file("./MainUI.glade")
builder.connect_signals(Handler())
window = builder.get_object("MainWindow")
window.connect("destroy",Gtk.main_quit)
window.show_all()
Gtk.main()
说回Gtk.Box,使用python代码也是可以实现布局UI的,如下就是放置了两个button
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Hello World")
# 设置容器之间的间隔是6个像素
self.box = Gtk.Box(spacing=6)
self.add(self.box)
self.button1 = Gtk.Button(label="Hello")
self.button1.connect("clicked", self.on_button1_clicked)
# 如果是垂直排列下面的函数就是添加button1到box从上向下放置,如果是横排就是从左到右放置
self.box.pack_start(self.button1, True, True, 0)
self.button2 = Gtk.Button(label="Goodbye")
self.button2.connect("clicked", self.on_button2_clicked)
# 如果是垂直排列下面的函数就是添加button2到box从下到上放置,如果是横排就是从右侧到左侧放置
self.box.pack_start(self.button2, True, True, 0)
def on_button1_clicked(self, widget):
print("Hello")
def on_button2_clicked(self, widget):
print("Goodbye")
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
Grid
顾名思义就是网格布局,wpf用的最多的就是grid,使用Gtk.Grid.attach()
方法添加子项,子项可以跨越多行或者多列。Gtk.Grid.attach()
有如下参数
可以使用Gtk.Grid.attach_next_to()
添加一个子项靠近当前已经存在的子项
下面是示例
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)
button1 = Gtk.Button(label="Button 1")
button2 = Gtk.Button(label="Button 2")
button3 = Gtk.Button(label="Button 3")
button4 = Gtk.Button(label="Button 4")
button5 = Gtk.Button(label="Button 5")
button6 = Gtk.Button(label="Button 6")
grid.add(button1)
grid.attach(button2, 1, 0, 2, 1)
grid.attach_next_to(button3, button1, Gtk.PositionType.BOTTOM, 1, 2)
grid.attach_next_to(button4, button3, Gtk.PositionType.RIGHT, 2, 1)
grid.attach(button5, 1, 2, 1, 1)
grid.attach_next_to(button6, button5, Gtk.PositionType.RIGHT, 1, 1)
win = GridWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
其他
box与grid最常用。 https://python-gtk-3-tutorial.readthedocs.io/en/latest/layout.html 中还有几个容器控件没有翻译,放到下面的图示上,用到再查手册就行。