PyGobject(七十八)Gtk.Builder篇

时间:2023-02-05 20:02:26

在前面的文章中,介绍完了常用的一些小部件。本篇将为大家介绍Gtk.Builder的使用。

Gtk.Builder

Gtk.Builder是一个辅助对象,通过读取用户定义好的UI文件(通常是使用glade生成)来获取部件,并将用户的UI展示出来。
PyGobject(七十八)Gtk.Builder篇

Methods

方法修饰词 方法名及参数
static new ()
static new_from_file (filename)
static new_from_resource (resource_path)
static new_from_string (string, length)
add_callback_symbol (callback_name, callback_symbol)
add_from_file (filename)
add_from_resource (resource_path)
add_from_string (buffer, length=-1)
add_objects_from_file (filename, object_ids)
add_objects_from_resource (resource_path, object_ids)
add_objects_from_string (buffer, object_ids)
connect_signals (self, obj_or_map)
connect_signals_full (func, *user_data)
expose_object (name, object)
extend_with_template (widget, template_type, buffer, length)
get_application ()
get_object (name)
get_objects ()
get_translation_domain ()
get_type_from_name (type_name)
set_application (application)
set_translation_domain (domain)
value_from_string (pspec, string)
value_from_string_type (type, string)

Virtual Methods

do_get_type_from_name (type_name)

Properties

Name Type Flags Short Description
translation-domain str r/w The translation domain used by gettext

Signals

Name Short Description

例子

一.Signal

PyGobject(七十八)Gtk.Builder篇
UI文件 example.glade

<?xml version="1.0" encoding="UTF-8"?>
<interface>
    <!-- interface-requires gtk+ 3.0 -->
    <object class="GtkWindow" id="window1">
        <property name="title">Signal Button</property>
        <property name="can_focus">False</property>
        <signal name="delete-event" handler="onDeleteWindow" swapped="no"/>
        <child>
            <object class="GtkButton" id="button1">
                <property name="label" translatable="yes">button</property>
                <property name="use_action_appearance">False</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="use_action_appearance">False</property>
                <signal name="pressed" handler="onButtonPressed" swapped="no"/>
            </object>
        </child>
    </object>
</interface>

代码:

#!/usr/bin/env python3
# Created by xiaosanyu at 16/6/16
# section 126
TITLE = "Signal"
DESCRIPTION = """ connect the button's signal """
import gi

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


class Handler:
    @staticmethod
    def onDeleteWindow(*args):
        Gtk.main_quit(*args)

    @staticmethod
    def onButtonPressed(button):
        print("Hello World!")


def main():
    builder = Gtk.Builder()
    builder.add_from_file(os.path.join(os.path.dirname(__file__), "../Data/example.glade"))
    builder.connect_signals(Handler())

    window = builder.get_object("window1")
    window.show_all()

    Gtk.main()


if __name__ == "__main__":
    main()

PyGobject(七十八)Gtk.Builder篇
UI文件 1.glade

<?xml version="1.0" encoding="UTF-8"?>
<interface>
    <!-- interface-requires gtk+ 3.0 -->
    <object class="GtkButton" id="label1">
         <signal name="clicked" handler="ok_button_clicked"/>
        <property name="label">I am a Label for a Button</property>
    </object>
    <object class="GtkButton" id="button1">
        <accessibility>
            <action action_name="click" translatable="yes">Click the button.</action>
            <relation target="label1" type="labelled-by"/>
        </accessibility>
        <child internal-child="accessible">
            <object class="AtkObject" id="a11y-button1">
                <property name="accessible-name">Clickable Button</property>
            </object>
        </child>
    </object>
</interface>

代码:

#!/usr/bin/env python3
# Created by xiaosanyu at 16/7/8
# section 122
TITLE = "Builder1"
DESCRIPTION = """ """
import gi

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


class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="UI DEMO")
        box = Gtk.VBox(spacing=6)
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(os.path.dirname(__file__), "1.glade"))
        builder.connect_signals(self)
        widget = builder.get_object("label1")
        box.add(widget)
        widget = builder.get_object("button1")
        box.add(widget)
        self.add(box)

    @staticmethod
    def ok_button_clicked(button):
        print("Hello World!")


def main():
    win = MyWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    Gtk.main()


if __name__ == '__main__':
    main()

三.顶层窗口为Dialog

PyGobject(七十八)Gtk.Builder篇

UI文件 2.glade

<?xml version="1.0" encoding="UTF-8"?>
<interface>
    <!-- interface-requires gtk+ 3.0 -->
    <object class="GtkDialog" id="dialog1">
        <signal name="delete-event" handler="onDeleteWindow" swapped="no"/>
        <child internal-child="vbox">
            <object class="GtkBox" id="vbox1">
                <property name="border-width">10</property>
                <child internal-child="action_area">
                    <object class="GtkButtonBox" id="hbuttonbox1">
                        <property name="border-width">20</property>
                        <child>
                            <object class="GtkButton" id="ok_button">
                                <property name="label">gtk-ok</property>
                                <property name="use-stock">TRUE</property>
                                <signal name="clicked" handler="ok_button_clicked"/>
                            </object>
                        </child>
                    </object>
                </child>
            </object>
        </child>
    </object>
</interface>

代码:

#!/usr/bin/env python3
# Created by xiaosanyu at 16/7/8
# section 123
TITLE = "Dialog"
DESCRIPTION = """ The toplevel window is a Dialog """
import gi

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


class Handler:
    @staticmethod
    def onDeleteWindow(*args):
        Gtk.main_quit(*args)

    @staticmethod
    def ok_button_clicked(button):
        print("Hello World!")


def main():
    builder = Gtk.Builder()
    builder.add_from_file(os.path.join(os.path.dirname(__file__), "2.glade"))
    builder.connect_signals(Handler())
    widget = builder.get_object("dialog1")
    widget.show_all()
    Gtk.main()


if __name__ == '__main__':
    main()

四.快捷键accelerator

PyGobject(七十八)Gtk.Builder篇
按“q”键激活按钮
UI文件 3.glade

<?xml version="1.0" encoding="UTF-8"?>
<interface>
    <!-- interface-requires gtk+ 3.0 -->
    <object class="GtkWindow" id="window1">
        <property name="can_focus">False</property>
        <signal name="delete-event" handler="onDeleteWindow" swapped="no"/>
        <child>
            <object class="GtkVBox" id="box1">
                <child>
                    <object class="GtkButton" id="button1">
                        <signal name="clicked" handler="ok_button_clicked"/>
                        <property name="label">Button</property>
                        <accelerator key="q" signal="clicked"/>
                    </object>
                </child>
                <child>
                    <object class="GtkButton" id="button2">
                        <property name="label">Button2</property>
                        <style> <class name="my-special-button-class"/> <class name="dark-button"/> </style>
                    </object>
                </child>
            </object>
        </child>
    </object>
</interface>

代码

#!/usr/bin/env python3
# Created by xiaosanyu at 16/7/8
# section 124
TITLE = "Accelerator"
DESCRIPTION = """ press "q" will active the button """
import gi

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


class Handler:
    @staticmethod
    def ok_button_clicked(button):
        print("Hello World!")

    @staticmethod
    def onDeleteWindow(*args):
        Gtk.main_quit(*args)


def main():
    builder = Gtk.Builder()
    builder.add_from_file(os.path.join(os.path.dirname(__file__), "3.glade"))

    builder.connect_signals(Handler())

    window = builder.get_object("window1")
    window.show_all()

    Gtk.main()


if __name__ == '__main__':
    main()

五.Template

PyGobject(七十八)Gtk.Builder篇

UI文件 4.glade

<?xml version="1.0" encoding="UTF-8"?>
<interface>
    <template class="%s" parent="GtkBox">
        <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
        <property name="spacing">4</property>
        <child>
            <object class="GtkButton" id="hello_button">
                <property name="label">Hello World</property>
                <signal name="clicked" handler="hello_button_clicked"/>
            </object>
        </child>
        <child>
            <object class="GtkButton" id="goodbye_button">
                <property name="label">Goodbye World</property>
            </object>
        </child>
    </template>
</interface>

代码:

#!/usr/bin/env python3
# Created by xiaosanyu at 16/7/8
# section 125
TITLE = "Template"
DESCRIPTION = """ Creates and initializes child widgets defined in templates. """
import gi

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, GObject, GLib
import os


class FooWidget(Gtk.Box):
    def __init__(self):
        data = Gio.resources_lookup_data("/templete/4.glade", 0)
        data = data.get_data().decode() % (__name__.replace(".", "+") + '+FooWidget')
        self.set_template(GLib.Bytes.new(data.encode()))

        super().__init__()

        # self.bind_template_callback_full("hello_button_clicked", self.hello_button_clicked)
        self.bind_template_child_full("goodbye_button", False, 0)
        self.bind_template_child_full("hello_button", False, 0)
        self.init_template()
        for child in self.get_children():
            child.connect("clicked", self.button_clicked, child.get_label())
        self.set_has_window(False)

    # Bug: Only click once
    @staticmethod
    def hello_button_clicked():
        print("hello_button_clicked")

    @staticmethod
    def button_clicked(widget, name):
        print(name + " clicked")


class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="UI DEMO")
        widget = FooWidget()
        # can't get child widget
        button1 = widget.get_template_child(Gtk.Button, "goodbye_button")
        print(button1)
        self.add(widget)


def main():
    win = MyWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    Gtk.main()


if __name__ == '__main__':
    base_path = os.path.abspath(os.path.dirname(__file__))
    resource_path = os.path.join(base_path, '../Data/demo.gresource')
    resource = Gio.Resource.load(resource_path)
    Gio.resources_register(resource)
    main()

六.

PyGobject(七十八)Gtk.Builder篇

UI文件 builder.glade

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<interface domain="gtk20">
    <object class="GtkListStore" id="liststore1">
        <columns>
            <column type="gchararray"/>
            <column type="gchararray"/>
            <column type="gint"/>
            <column type="gchararray"/>
        </columns>
        <data>
            <row>
                <col id="0" translatable="yes">John</col>
                <col id="1" translatable="yes">Doe</col>
                <col id="2">25</col>
                <col id="3" translatable="yes">This is the John Doe row</col>
            </row>
            <row>
                <col id="0" translatable="yes">Mary</col>
                <col id="1" translatable="yes">Unknown</col>
                <col id="2">50</col>
                <col id="3" translatable="yes">This is the Mary Unknown row</col>
            </row>
        </data>
    </object>
    <object class="GtkUIManager" id="uimanager">
        <child>
            <object class="GtkActionGroup" id="DefaultActions">
                <child>
                    <object class="GtkAction" id="Copy">
                        <property name="name">Copy</property>
                        <property name="tooltip" translatable="yes">Copy selected object into the clipboard</property>
                        <property name="stock_id">gtk-copy</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="Cut">
                        <property name="name">Cut</property>
                        <property name="tooltip" translatable="yes">Cut selected object into the clipboard</property>
                        <property name="stock_id">gtk-cut</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="EditMenu">
                        <property name="name">EditMenu</property>
                        <property name="label" translatable="yes">_Edit</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="FileMenu">
                        <property name="name">FileMenu</property>
                        <property name="label" translatable="yes">_File</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="New">
                        <property name="name">New</property>
                        <property name="tooltip" translatable="yes">Create a new file</property>
                        <property name="stock_id">gtk-new</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="Open">
                        <property name="name">Open</property>
                        <property name="tooltip" translatable="yes">Open a file</property>
                        <property name="stock_id">gtk-open</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="Paste">
                        <property name="name">Paste</property>
                        <property name="tooltip" translatable="yes">Paste object from the Clipboard</property>
                        <property name="stock_id">gtk-paste</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="Quit">
                        <property name="name">Quit</property>
                        <property name="tooltip" translatable="yes">Quit the program</property>
                        <property name="stock_id">gtk-quit</property>
                        <signal handler="quit_activate" name="activate"/>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="Save">
                        <property name="name">Save</property>
                        <property name="is_important">True</property>
                        <property name="tooltip" translatable="yes">Save a file</property>
                        <property name="stock_id">gtk-save</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="SaveAs">
                        <property name="name">SaveAs</property>
                        <property name="tooltip" translatable="yes">Save with a different name</property>
                        <property name="stock_id">gtk-save-as</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="HelpMenu">
                        <property name="name">HelpMenu</property>
                        <property name="label" translatable="yes">_Help</property>
                    </object>
                </child>
                <child>
                    <object class="GtkAction" id="About">
                        <property name="name">About</property>
                        <property name="stock_id">gtk-about</property>
                        <signal handler="about_activate" name="activate"/>
                    </object>
                    <accelerator key="F1"/>
                </child>
            </object>
        </child>
        <ui>
            <menubar name="menubar1">
                <menu action="FileMenu" name="FileMenu">
                    <menuitem action="New" name="New"/>
                    <menuitem action="Open" name="Open"/>
                    <menuitem action="Save" name="Save"/>
                    <menuitem action="SaveAs" name="SaveAs"/>
                    <separator/>
                    <menuitem action="Quit" name="Quit"/>
                </menu>
                <menu action="EditMenu">
                    <menuitem action="Copy" name="Copy"/>
                    <menuitem action="Cut" name="Cut"/>
                    <menuitem action="Paste" name="Paste"/>
                </menu>
                <menu action="HelpMenu" name="HelpMenu">
                    <menuitem action="About" name="About"/>
                </menu>
            </menubar>
            <toolbar name="toolbar1">
                <toolitem action="New" name="New"/>
                <toolitem action="Open" name="Open"/>
                <toolitem action="Save" name="Save"/>
                <separator/>
                <toolitem action="Copy" name="Copy"/>
                <toolitem action="Cut" name="Cut"/>
                <toolitem action="Paste" name="Paste"/>
            </toolbar>
        </ui>
    </object>
    <object class="GtkAboutDialog" id="aboutdialog1">
        <property name="program-name" translatable="yes">GtkBuilder demo</property>
        <accessibility>
            <relation target="window1" type="subwindow-of"/>
        </accessibility>
    </object>
    <object class="GtkWindow" id="window1">
        <property name="default_height">250</property>
        <property name="default_width">440</property>
        <property name="title">GtkBuilder demo</property>
        <child>
            <object class="GtkVBox" id="vbox1">
                <property name="visible">True</property>
                <child>
                    <object constructor="uimanager" class="GtkMenuBar" id="menubar1">
                        <property name="visible">True</property>
                        <child internal-child="accessible">
                            <object class="AtkObject" id="a11y-menubar">
                                <property name="AtkObject::accessible-name">The menubar</property>
                            </object>
                        </child>
                    </object>
                    <packing>
                        <property name="expand">False</property>
                    </packing>
                </child>
                <child>
                    <object constructor="uimanager" class="GtkToolbar" id="toolbar1">
                        <property name="visible">True</property>
                        <child internal-child="accessible">
                            <object class="AtkObject" id="a11y-toolbar">
                                <property name="AtkObject::accessible-name">The toolbar</property>
                            </object>
                        </child>
                    </object>
                    <packing>
                        <property name="expand">False</property>
                        <property name="position">1</property>
                    </packing>
                </child>
                <child>
                    <object class="GtkScrolledWindow" id="scrolledwindow1">
                        <property name="hscrollbar_policy">automatic</property>
                        <property name="shadow_type">in</property>
                        <property name="visible">True</property>
                        <property name="vscrollbar_policy">automatic</property>
                        <child>
                            <object class="GtkTreeView" id="treeview1">
                                <property name="visible">True</property>
                                <property name="model">liststore1</property>
                                <property name="tooltip-column">3</property>
                                <child internal-child="accessible">
                                    <object class="AtkObject" id="a11y-treeview">
                                        <property name="AtkObject::accessible-name">Name list</property>
                                        <property name="AtkObject::accessible-description">
                                            A list of person with name, surname and age columns
                                        </property>
                                    </object>
                                </child>
                                <child>
                                    <object class="GtkTreeViewColumn" id="column1">
                                        <property name="title">Name</property>
                                        <child>
                                            <object class="GtkCellRendererText" id="renderer1"/>
                                            <attributes>
                                                <attribute name="text">0</attribute>
                                            </attributes>
                                        </child>
                                    </object>
                                </child>
                                <child>
                                    <object class="GtkTreeViewColumn" id="column2">
                                        <property name="title">Surname</property>
                                        <child>
                                            <object class="GtkCellRendererText" id="renderer2"/>
                                            <attributes>
                                                <attribute name="text">1</attribute>
                                            </attributes>
                                        </child>
                                    </object>
                                </child>
                                <child>
                                    <object class="GtkTreeViewColumn" id="column3">
                                        <property name="title">Age</property>
                                        <child>
                                            <object class="GtkCellRendererText" id="renderer3"/>
                                            <attributes>
                                                <attribute name="text">2</attribute>
                                            </attributes>
                                        </child>
                                    </object>
                                </child>
                            </object>
                        </child>
                        <accessibility>
                            <action action_name="move-cursor" description="Move the cursor to select another person."/>
                        </accessibility>
                    </object>
                    <packing>
                        <property name="position">2</property>
                    </packing>
                </child>
                <child>
                    <object class="GtkStatusbar" id="statusbar1">
                        <property name="visible">True</property>
                    </object>
                    <packing>
                        <property name="expand">False</property>
                        <property name="position">3</property>
                    </packing>
                </child>
            </object>
        </child>
    </object>
</interface>

代码:

#!/usr/bin/env python3
# section 127
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2010 Red Hat, Inc., John (J5) Palmieri <johnp@redhat.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA

TITLE = "Builder"
DESCRIPTION = """ Demonstrates an interface loaded from a XML description. """

import os
import gi

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


class BuilderApp:
    def __init__(self):
        self.builder = Gtk.Builder()
        filename = os.path.join(os.path.dirname(__file__), '../Data', 'builder.glade')
        self.builder.add_from_file(filename)
        self.builder.connect_signals(self)

        self.window = self.builder.get_object('window1')
        self.window.connect('destroy', lambda x: Gtk.main_quit())
        self.window.show_all()

    def about_activate(self, action):
        about_dlg = self.builder.get_object('aboutdialog1')
        # set logo
        icon = GdkPixbuf.Pixbuf.new_from_file(os.path.join(os.path.dirname(__file__), "../Data/gtk-logo-rgb.gif"))
        # transparent
        icon = icon.add_alpha(True, 0xff, 0xff, 0xff)
        about_dlg.set_logo(icon)
        about_dlg.run()
        about_dlg.destroy()

    def quit_activate(self, action):
        self.window.destroy()
        Gtk.main_quit()


def main():
    BuilderApp()
    Gtk.main()


if __name__ == '__main__':
    main()





代码下载地址:http://download.csdn.net/detail/a87b01c14/9594728