当前位置: 首页 > 文档资料 > PyGTK 教程 >

02 PyGTK 中的布局管理

优质
小牛编辑
129浏览
2023-12-01

本教程在这章中,我们将怎样在窗口或者对话框(dialogs)中布置我们的部件。

当我们设计程序的GUI界面时,我们决定哪些部件我们将会使用,和我们将怎样在程序中组织那些部件。为了组织我们的部件,我们使用专门的不可见部件,其被称为布局容器layout containers)。在这章中,我们将提到Alignment, Fixed, VBoxTable这四种布局容器(layout containers)。

Fixed

Fixed容器将放置位置固定和尺寸固定的子部件。这个容器不进行自动的布局管理。在大多数的程序中,我们不用这种容器。但是在一些专门的领域,我们会用它。例如游戏,一些工作在图表中的专门程序,那些能被移动可变化尺寸的组件(就想在电子表格程序中的一个chart表一样),小型的学习示例等。

Code:fixed.py

#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example demonstrates a Fixed
# container widget
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009

import gtk
import sys

class PyApp(gtk.Window):

    def __init__(self):
        super(PyApp, self).__init__()

        self.set_title("Fixed")
        self.set_size_request(300, 280)
        self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(6400, 6400, 6440))
        self.set_position(gtk.WIN_POS_CENTER)

        try:
            self.bardejov = gtk.gdk.pixbuf_new_from_file("bardejov.jpg")
            self.rotunda = gtk.gdk.pixbuf_new_from_file("rotunda.jpg")
            self.mincol = gtk.gdk.pixbuf_new_from_file("mincol.jpg")
        except Exception, e:
            print e.message
            sys.exit(1)
        
        
        image1 = gtk.Image()
        image2 = gtk.Image()
        image3 = gtk.Image()
        
        image1.set_from_pixbuf(self.bardejov)
        image2.set_from_pixbuf(self.rotunda)
        image3.set_from_pixbuf(self.mincol)
               
        fix = gtk.Fixed()
           
        fix.put(image1, 20, 20)
        fix.put(image2, 40, 160)
        fix.put(image3, 170, 50)

        self.add(fix)

        self.connect("destroy", gtk.main_quit)
        self.show_all()
        

PyApp()

gtk.main()

在我们的例子中,我们在窗口上显示了3个小图片。在我们放置这些图片的地方,我们明确地指定其x,y坐标。

self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(6400, 6400, 6440))

为了更好的视觉体验,我们更改了窗口的背景颜色为暗灰色。

self.bardejov = gtk.gdk.pixbuf_new_from_file("bardejov.jpg")

我们从磁盘中一个文件里载入图片。

image1 = gtk.Image()
image2 = gtk.Image()
image3 = gtk.Image()

image1.set_from_pixbuf(self.bardejov)
image2.set_from_pixbuf(self.rotunda)
image3.set_from_pixbuf(self.mincol)

Image是一个部件,其作用是用来显示图片的。它在构造函数占用了一个Pixbuf(图片缓存)对象。

fix = gtk.Fixed()

我们创建了Fixed容器。

fix.put(image1, 20, 20)

我们将第一张图片放置在坐标为x=20,y=20的位置上。

self.add(fix)

最后,我们将Fixed容器添加到窗口中。

Figure:Fixed

Alignment

Alignment容器控制它的子部件的对齐和尺寸。

Code:alignment.py

#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example shows how to use
# the Alignment widget
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009

import gtk

class PyApp(gtk.Window):

    def __init__(self):
        super(PyApp, self).__init__()

        self.set_title("Alignment")
        self.set_size_request(260, 150)
        self.set_position(gtk.WIN_POS_CENTER)

        vbox = gtk.VBox(False, 5)
        hbox = gtk.HBox(True, 3)
        
        valign = gtk.Alignment(0, 1, 0, 0)
        vbox.pack_start(valign)
        
        ok = gtk.Button("OK")
        ok.set_size_request(70, 30)
        close = gtk.Button("Close")
        
        hbox.add(ok)
        hbox.add(close)
        
        halign = gtk.Alignment(1, 0, 0, 0)
        halign.add(hbox)
        
        vbox.pack_start(halign, False, False, 3)

        self.add(vbox)

        self.connect("destroy", gtk.main_quit)
        self.show_all()
        

PyApp()
gtk.main()

在上述代码示例中,我们放置了两个按钮在窗口的右下角。为了完成这项任务,我们使用了一个水平箱子容器(horizontal box)和一个垂直箱子容器(vertical box)以及两个alignment容器。

valign = gtk.Alignment(0, 1, 0, 0)

这一步将会放置小部件到底部。

vbox.pack_start(valign)

在这里,我们Alignment容器放置到垂直箱子容器中。

hbox = gtk.HBox(True, 3)
...
ok = gtk.Button("OK")
ok.set_size_request(70, 30)
close = gtk.Button("Close")

hbox.add(ok)
hbox.add(close)

我们创建了一个水平箱子容器,并放置了两个按钮到其中。

halign = gtk.Alignment(1, 0, 0, 0)
halign.add(hbox)

vbox.pack_start(halign, False, False, 3)

这将创建一个alignment容器,这个容器将放置其子部件到右边。我们添加水平箱子容器到alignment容器中,并将alignment容器放置进垂直箱子容器中。我们必须记住的是:alignment容器中只能有一个子部件。这就是为什么我们必须用box容器。

Figure:alignment

【译者理解:alignment容器的位置按顺序分别是gtk.alignment(右,下,上,左)】

Table

Table容器部件是将其部件安排在行和列中。

Code:calculator.py

#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example shows how to use
# the Table container widget
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009

import gtk

class PyApp(gtk.Window):

    def __init__(self):
        super(PyApp, self).__init__()

        self.set_title("Calculator")
        self.set_size_request(250, 230)
        self.set_position(gtk.WIN_POS_CENTER)

        vbox = gtk.VBox(False, 2)
        
        mb = gtk.MenuBar()
        filemenu = gtk.Menu()
        filem = gtk.MenuItem("File")
        filem.set_submenu(filemenu)
        mb.append(filem)

        vbox.pack_start(mb, False, False, 0)

        table = gtk.Table(5, 4, True)

        table.attach(gtk.Button("Cls"), 0, 1, 0, 1)
        table.attach(gtk.Button("Bck"), 1, 2, 0, 1)
        table.attach(gtk.Label(), 2, 3, 0, 1)
        table.attach(gtk.Button("Close"), 3, 4, 0, 1)

        table.attach(gtk.Button("7"), 0, 1, 1, 2)
        table.attach(gtk.Button("8"), 1, 2, 1, 2)
        table.attach(gtk.Button("9"), 2, 3, 1, 2)
        table.attach(gtk.Button("/"), 3, 4, 1, 2)

        table.attach(gtk.Button("4"), 0, 1, 2, 3)
        table.attach(gtk.Button("5"), 1, 2, 2, 3)
        table.attach(gtk.Button("6"), 2, 3, 2, 3)
        table.attach(gtk.Button("*"), 3, 4, 2, 3)

        table.attach(gtk.Button("1"), 0, 1, 3, 4)
        table.attach(gtk.Button("2"), 1, 2, 3, 4)
        table.attach(gtk.Button("3"), 2, 3, 3, 4)
        table.attach(gtk.Button("-"), 3, 4, 3, 4)

        table.attach(gtk.Button("0"), 0, 1, 4, 5)
        table.attach(gtk.Button("."), 1, 2, 4, 5)
        table.attach(gtk.Button("="), 2, 3, 4, 5)
        table.attach(gtk.Button("+"), 3, 4, 4, 5)

        vbox.pack_start(gtk.Entry(), False, False, 0)
        vbox.pack_end(table, True, True, 0)

        self.add(vbox)

        self.connect("destroy", gtk.main_quit)
        self.show_all()
        

PyApp()
gtk.main()

我们用Table容器部件创建了一个计算器的框架。

table = gtk.Table(5, 4, True)

我们创建了一个5行4列的table容器部件。第三个参数是同质参数,如果被设置为ture,table中所有的部件将是相同的尺寸。而所有部件的尺寸与table容器中最大的部件的尺寸相同。

table.attach(gtk.Button("Cls"), 0, 1, 0, 1)

我们附加了一个按钮到table容器中,其位置在表格的左上单元(cell)。前面两个参数代表这个单元的左侧和右侧,后两个参数代表这个单元的上部和下部。【译者:此处表述比较难以理解,待研究。】

vbox.pack_end(table, True, True, 0)

我们将table容器部件放置到垂直箱子容器中。

Figure:Calculator skeleton

Windows

下面我们将创建一个更加高级的例子。我们展示了一个窗口,其可以在JDeveloper 集成开发环境(IDE)中被找到。

Code:windows.py

#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This is a more complicated layout
# example
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009

import gtk
import sys

class PyApp(gtk.Window):

    def __init__(self):
        super(PyApp, self).__init__()

        self.set_title("Windows")
        self.set_size_request(300, 250)
        self.set_border_width(8)
        self.set_position(gtk.WIN_POS_CENTER)

        table = gtk.Table(8, 4, False)
        table.set_col_spacings(3)

        title = gtk.Label("Windows")

        halign = gtk.Alignment(0, 0, 0, 0)
        halign.add(title)
        
        table.attach(halign, 0, 1, 0, 1, gtk.FILL, 
            gtk.FILL, 0, 0);

        wins = gtk.TextView()
        wins.set_editable(False)
        wins.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(5140, 5140, 5140))
        wins.set_cursor_visible(False)
        table.attach(wins, 0, 2, 1, 3, gtk.FILL | gtk.EXPAND,
            gtk.FILL | gtk.EXPAND, 1, 1)

        activate = gtk.Button("Activate")
        activate.set_size_request(50, 30)
        table.attach(activate, 3, 4, 1, 2, gtk.FILL, 
            gtk.SHRINK, 1, 1)
        
        valign = gtk.Alignment(0, 0, 0, 0)
        close = gtk.Button("Close")
        close.set_size_request(70, 30)
        valign.add(close)
        table.set_row_spacing(1, 3)
        table.attach(valign, 3, 4, 2, 3, gtk.FILL,
            gtk.FILL | gtk.EXPAND, 1, 1)
            
        halign2 = gtk.Alignment(0, 1, 0, 0)
        help = gtk.Button("Help")
        help.set_size_request(70, 30)
        halign2.add(help)
        table.set_row_spacing(3, 6)
        table.attach(halign2, 0, 1, 4, 5, gtk.FILL, 
            gtk.FILL, 0, 0)
        
        ok = gtk.Button("OK")
        ok.set_size_request(70, 30)
        table.attach(ok, 3, 4, 4, 5, gtk.FILL, 
            gtk.FILL, 0, 0);
                          
        self.add(table)

        self.connect("destroy", gtk.main_quit)
        self.show_all()
        

PyApp()
gtk.main()

上述代码示例中展示了,我们在PyGTK中怎样创建相似的窗口。

table = gtk.Table(8, 4, False)
table.set_col_spacings(3)

这个例子是基于table容器的。在每一列中间将有3个像素(px)的间隔。

title = gtk.Label("Windows")

halign = gtk.Alignment(0, 0, 0, 0)
halign.add(title)

table.attach(halign, 0, 1, 0, 1, gtk.FILL, 
    gtk.FILL, 0, 0);

上述代码创建了一个文本标签(label),其被排在左边。这个文本标签(label)被放置在Table容器的第一行。

wins = gtk.TextView()
wins.set_editable(False)
wins.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(5140, 5140, 5140))
wins.set_cursor_visible(False)
table.attach(wins, 0, 2, 1, 3, gtk.FILL | gtk.EXPAND,
    gtk.FILL | gtk.EXPAND, 1, 1)

上述代码中的文本视图(TextView)部件跨越了两行两列。我们使其不可编辑,并隐藏了光标。

valign = gtk.Alignment(0, 0, 0, 0)
close = gtk.Button("Close")
close.set_size_request(70, 30)
valign.add(close)
table.set_row_spacing(1, 3)
table.attach(valign, 3, 4, 2, 3, gtk.FILL,
    gtk.FILL | gtk.EXPAND, 1, 1)

我们将close按钮放进紧接着文本视图部件的第四列中(我们从0数起)。我们将按钮添加进alignment部件,这样我们就能将它排在顶部。

Figure:Windows

PyGTK编程教程的这章是关于布局管理(layout management)。