PyGobject(一百一十)代码整合及GtkSource安装使用

来源:互联网 发布:access数据库开发软件 编辑:程序博客网 时间:2024/06/16 02:54

  • 例子
  • GtkSource安装

官方demo中所有的例子程序最后都是在一个gtk-demo.py中展现出来的。本文稍微有做一点修改。就是左侧目录可以展示多级子目录。

例子

先上一张效果图
这里写图片描述
代码:

#!/usr/bin/env python3# -*- 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# USAimport codecsimport osimport sysimport textwrapimport globimport gigi.require_version('Pango', '1.0')gi.require_version('GdkPixbuf', '2.0')gi.require_version('Gtk', '3.0')from gi.repository import GLib, GObject, Pango, GdkPixbuf, Gtk, Giotry:    gi.require_version('GtkSource', '3.0')    from gi.repository import GtkSource  # PyFlakesexcept Exception:    GtkSource = NoneDEMOROOTDIR = os.path.abspath(os.path.dirname(__file__))DEMOCODEDIR = os.path.join(DEMOROOTDIR, 'demos')sys.path.insert(0, DEMOROOTDIR)class Demo(GObject.GObject):    __gtype_name__ = 'GtkDemo'    def __init__(self, title, module, filename):        super(Demo, self).__init__()        self.title = title        self.module = module        self.filename = filename    @classmethod    def new_from_file(cls, path):        relpath = os.path.relpath(path, DEMOROOTDIR)        packagename = os.path.dirname(relpath).replace(os.sep, '.')        modulename = os.path.splitext(os.path.basename(relpath))[0]        try:            package = __import__(packagename, globals(), locals(), [modulename], 0)            module = getattr(package, modulename)            return cls(module.TITLE, module, path)        except AttributeError as e:            raise AttributeError('(%s): %s' % (path, e))class DemoTreeStore(Gtk.TreeStore):    __gtype_name__ = 'GtkDemoTreeStore'    def __init__(self, *args):        super(DemoTreeStore, self).__init__(str, Demo, Pango.Style)        self._parent_nodes = {}        self._list_dir(DEMOCODEDIR)    def _list_dir(self, path):        for filename in glob.glob(path + "/[!__]*"):            if os.path.isdir(filename):                self._list_dir(filename)            elif os.path.isfile(filename) and filename.endswith(".py"):                parentname = os.path.dirname(os.path.relpath(filename, DEMOCODEDIR))                if parentname:                    parent = self._get_parent_node(parentname)                else:                    parent = None                demo = Demo.new_from_file(filename)                self.append(parent, (demo.title, demo, Pango.Style.NORMAL))    def _get_parent_node(self, name):        if name not in self._parent_nodes.keys():            parent_path, current_path = self._get_parent_path(name)            if parent_path:                node = self.append(self._get_parent_node(parent_path), (current_path, None, Pango.Style.NORMAL))            else:                node = self.append(None, (name, None, Pango.Style.NORMAL))            self._parent_nodes[name] = node        return self._parent_nodes[name]    @staticmethod    def _get_parent_path(path):        index = path.rfind(os.sep)        if index != -1:            return path[0:index], path[index + 1:]        else:            return None, Noneclass GtkDemoApp(Gtk.Application):    __gtype_name__ = 'GtkDemoWindow'    def __init__(self):        super(GtkDemoApp, self).__init__(application_id='org.gnome.pygobject.gtkdemo')        # Use a GResource to hold the CSS files. Resource bundles are created by        # the glib-compile-resources program shipped with Glib which takes an xml        # file that describes the bundle, and a set of files that the xml        # references. These are combined into a binary resource bundle.        base_path = os.path.abspath(os.path.dirname(__file__))        resource_path = os.path.join(base_path, 'demos/Data/demo.gresource')        resource = Gio.Resource.load(resource_path)        # FIXME: method register() should be without the underscore        # FIXME: see https://bugzilla.gnome.org/show_bug.cgi?id=684319        # Once the resource has been globally registered it can be used        # throughout the application.        Gio.resources_register(resource)    def on_activate(self, app):        self.window = Gtk.ApplicationWindow.new(self)        self.window.set_title('PyGObject GTK+ Code Demos')        self.window.set_default_size(600, 400)        self.setup_default_icon()        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,                       homogeneous=False,                       spacing=0)        self.window.add(hbox)        tree = self.create_tree()        hbox.pack_start(child=tree, expand=False, fill=False, padding=0)        # Right vbox contains info/source panels        right_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,                             homogeneous=False,                             spacing=0)        hbox.pack_start(child=right_vbox, expand=True, fill=True, padding=0)        stack = Gtk.Stack(transition_type=Gtk.StackTransitionType.SLIDE_LEFT_RIGHT,                          homogeneous=True)        switcher = Gtk.StackSwitcher(stack=stack)        right_vbox.pack_start(child=switcher, expand=False, fill=False, padding=0)        right_vbox.pack_start(child=stack, expand=True, fill=True, padding=0)        text_widget, info_buffer = self.create_text_view()        stack.add_titled(text_widget, name='info', title='Info')        self.info_buffer = info_buffer        self.info_buffer.create_tag('title', font='Sans 18')        text_widget, self.source_buffer = self.create_source_view()        stack.add_titled(text_widget, name='source', title='Source')        self.window.show_all()        self.selection_cb(self.tree_view.get_selection(),                          self.tree_view.get_model())    @staticmethod    def find_file(base=''):        dir = os.path.join(DEMOCODEDIR, 'data')        logo_file = os.path.join(dir, 'gtk-logo-rgb.gif')        base_file = os.path.join(dir, base)        if (GLib.file_test(logo_file, GLib.FileTest.EXISTS) and                GLib.file_test(base_file, GLib.FileTest.EXISTS)):            return base_file        else:            filename = os.path.join(DEMOCODEDIR, base)            if GLib.file_test(filename, GLib.FileTest.EXISTS):                return filename            # can't find the file            raise IOError('Cannot find demo data file "%s"' % base)    def setup_default_icon(self):        filename = self.find_file('gtk-logo-rgb.gif')        pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename)        transparent = pixbuf.add_alpha(True, 0xff, 0xff, 0xff)        list = []        list.append(transparent)        Gtk.Window.set_default_icon_list(list)    def selection_cb(self, selection, model):        sel = selection.get_selected()        if sel == ():            return        treeiter = sel[1]        title = model.get_value(treeiter, 0)        demo = model.get_value(treeiter, 1)        if demo is None:            return        # Split into paragraphs based on double newlines and use        # textwrap to strip out all other formatting whitespace        description = ''        for paragraph in demo.module.DESCRIPTION.split('\n\n'):            description += '\n'.join(textwrap.wrap(paragraph, 99999))            description += '\n\n'  # Add paragraphs back in        f = codecs.open(demo.filename, 'rU', 'utf-8')        code = f.read()        f.close()        # output and style the title        (start, end) = self.info_buffer.get_bounds()        self.info_buffer.delete(start, end)        (start, end) = self.source_buffer.get_bounds()        self.source_buffer.delete(start, end)        start = self.info_buffer.get_iter_at_offset(0)        end = start.copy()        self.info_buffer.insert(end, title)        start = end.copy()        start.backward_chars(len(title))        self.info_buffer.apply_tag_by_name('title', start, end)        self.info_buffer.insert(end, '\n')        # output the description        self.info_buffer.insert(end, description)        # output the code        start = self.source_buffer.get_iter_at_offset(0)        end = start.copy()        self.source_buffer.insert(end, code)    @staticmethod    def row_activated_cb(view, path, col, store):        iter = store.get_iter(path)        demo = store.get_value(iter, 1)        if demo is not None:            store.set_value(iter, 2, Pango.Style.ITALIC)            try:                demo.module.main()            except Exception as e:                print(demo.module)                raise e            finally:                store.set_value(iter, 2, Pango.Style.NORMAL)    def create_tree(self):        tree_store = DemoTreeStore()        tree_view = Gtk.TreeView()        self.tree_view = tree_view        tree_view.set_model(tree_store)        selection = tree_view.get_selection()        selection.set_mode(Gtk.SelectionMode.BROWSE)        tree_view.set_size_request(200, -1)        cell = Gtk.CellRendererText()        column = Gtk.TreeViewColumn(title='Widget (double click for demo)',                                    cell_renderer=cell,                                    text=0,                                    style=2)        first_iter = tree_store.get_iter_first()        if first_iter is not None:            selection.select_iter(first_iter)        selection.connect('changed', self.selection_cb, tree_store)        tree_view.connect('row_activated', self.row_activated_cb, tree_store)        tree_view.append_column(column)        # tree_view.expand_all()        tree_view.set_headers_visible(False)        scrolled_window = Gtk.ScrolledWindow(hadjustment=None,                                             vadjustment=None)        scrolled_window.set_policy(Gtk.PolicyType.NEVER,                                   Gtk.PolicyType.AUTOMATIC)        scrolled_window.add(tree_view)        label = Gtk.Label(label='Widget (double click for demo)')        box = Gtk.Notebook()        box.append_page(scrolled_window, label)        tree_view.grab_focus()        return box    @staticmethod    def create_scrolled_window():        scrolled_window = Gtk.ScrolledWindow(hadjustment=None,                                             vadjustment=None)        scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,                                   Gtk.PolicyType.AUTOMATIC)        scrolled_window.set_shadow_type(Gtk.ShadowType.IN)        return scrolled_window    def create_text_view(self):        text_view = Gtk.TextView()        buffer = Gtk.TextBuffer()        text_view.set_buffer(buffer)        text_view.set_editable(False)        text_view.set_cursor_visible(False)        scrolled_window = self.create_scrolled_window()        scrolled_window.add(text_view)        text_view.set_wrap_mode(Gtk.WrapMode.WORD)        text_view.set_pixels_above_lines(2)        text_view.set_pixels_below_lines(2)        return scrolled_window, buffer    def create_source_view(self):        font_desc = Pango.FontDescription('monospace 13')        if GtkSource:            lang_mgr = GtkSource.LanguageManager.get_default()            # print(lang_mgr.get_language_ids())            lang = lang_mgr.get_language('python3')            buffer = GtkSource.Buffer()            buffer.set_language(lang)            buffer.set_highlight_syntax(True)            view = GtkSource.View()            view.set_buffer(buffer)            view.set_show_line_numbers(True)            scrolled_window = self.create_scrolled_window()            scrolled_window.add(view)        else:            scrolled_window, buffer = self.create_text_view()            view = scrolled_window.get_child()        view.modify_font(font_desc)        view.set_wrap_mode(Gtk.WrapMode.NONE)        return scrolled_window, buffer    def run(self, argv):        self.connect('activate', self.on_activate)        return super(GtkDemoApp, self).run(argv)def main(argv):    """Entry point for demo manager"""    app = GtkDemoApp()    return app.run(argv)if __name__ == '__main__':    SystemExit(main(sys.argv))

GtkSource安装

要显示Python风格的源代码,需要安装GtkSource
具体方法为:

jhbuild build gtksourceview

安装完成后还需要把gtksourceview一些样式装到系统本地路径

cd /Users/xiaosanyu/gtk/source/gtksourceview ./configuremake make install

可惜我的安装好后,只能显示行号,没有彩色关键字,报如下错误

(gtk-demo.py:22336): Gdk-WARNING **: GdkQuartzDisplay does not implement the monitor vfuncs
/Applications/Project/Python/project/PYGUI/pygtk3/gtk-demo.py:333: Warning: unknown option bit(s) set
buffer.set_language(lang)
/Applications/Project/Python/project/PYGUI/pygtk3/gtk-demo.py:333: Warning: g_regex_match_full: assertion ‘regex != NULL’ failed
buffer.set_language(lang)
/Applications/Project/Python/project/PYGUI/pygtk3/gtk-demo.py:333: Warning: g_regex_replace_eval: assertion ‘regex != NULL’ failed
buffer.set_language(lang)
/Applications/Project/Python/project/PYGUI/pygtk3/gtk-demo.py:333: Warning: g_regex_unref: assertion ‘regex != NULL’ failed
buffer.set_language(lang)
(gtk-demo.py:22336): GtkSourceView-WARNING **: in file /usr/local/share/gtksourceview-3.0/language-specs/python3.lang: style ‘python:module-handler’ not defined
(gtk-demo.py:22336): GtkSourceView-WARNING **: Failed to load ‘/usr/local/share/gtksourceview-3.0/language-specs/python3.lang’: style override used with wildcard context reference in language ‘python3’ in ref ‘def:line-continue’

貌似是正则库没有装好,还请有装好的朋友给个参考方法

20160804
更新:pcre正则匹配原因找到了

修改/Users/xiaosanyu/gtk/source/glib/glib/gregex.c
大约1420行

 re = pcre_compile2 (pattern, compile_options, &errcode,                      &errmsg, &erroffset, NULL);

改成

 re = pcre_compile2 (pattern, 0, &errcode,                      &errmsg, &erroffset, NULL);

然后重新编译glib

jhbuild build glib

OK,大功告成,开心~~~~~





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

0 0
原创粉丝点击