Редактирование: PyGTK FAQ Pango
Материал из Wiki.crossplatform.ru
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
+ | In this part of the PyGTK programming tutorial, we will explore the Pango library. | ||
+ | Pango is a free and open source computing library for rendering internationalized texts in high quality. Different font backends can be used, allowing cross-platform support. | ||
+ | (wikipedia) Pango provides advanced font and text handling that is used for <b>Gdk</b> and <b>Gtk</b>. | ||
+ | |||
+ | == Simple example == | ||
+ | In our first example, we show, how to change font for our label widget. | ||
+ | <source lang="python"> | ||
+ | #!/usr/bin/python | ||
+ | # ZetCode PyGTK tutorial | ||
+ | # | ||
+ | # This example shows how to modify | ||
+ | # the font of a label | ||
+ | # | ||
+ | # author: jan bodnar | ||
+ | # website: zetcode.com | ||
+ | # last edited: February 2009 | ||
+ | |||
+ | import gtk | ||
+ | import pango | ||
+ | |||
+ | quotes = """Excess of joy is harder to bear than any amount of sorrow. | ||
+ | The more one judges, the less one loves. | ||
+ | There is no such thing as a great talent without great will power. | ||
+ | """ | ||
+ | |||
+ | class PyApp(gtk.Window): | ||
+ | def __init__(self): | ||
+ | super(PyApp, self).__init__() | ||
+ | |||
+ | self.connect("destroy", gtk.main_quit) | ||
+ | self.set_title("Quotes") | ||
+ | |||
+ | label = gtk.Label(quotes) | ||
+ | gtk.gdk.beep() | ||
+ | |||
+ | fontdesc = pango.FontDescription("Purisa 10") | ||
+ | label.modify_font(fontdesc) | ||
+ | |||
+ | fix = gtk.Fixed() | ||
+ | |||
+ | fix.put(label, 5, 5) | ||
+ | |||
+ | self.add(fix) | ||
+ | self.set_position(gtk.WIN_POS_CENTER) | ||
+ | self.show_all() | ||
+ | |||
+ | PyApp() | ||
+ | gtk.main() | ||
+ | </source> | ||
+ | |||
+ | In the above code example, we have a label widget with three quotations. We change it's font to Purisa 10. | ||
+ | |||
+ | <source lang="python"> | ||
+ | quotes = """Excess of joy is harder to bear than any amount of sorrow. | ||
+ | The more one judges, the less one loves. | ||
+ | There is no such thing as a great talent without great will power. | ||
+ | """ | ||
+ | </source> | ||
+ | |||
+ | This is the text to show in the label. | ||
+ | |||
+ | <source lang="python"> | ||
+ | fontdesc = pango.FontDescription("Purisa 10") | ||
+ | </source> | ||
+ | |||
+ | The <b>FontDescription</b> is used to specify the characteristics of a font. | ||
+ | |||
+ | <source lang="python"> | ||
+ | label.modify_font(fontdesc) | ||
+ | </source> | ||
+ | |||
+ | We change the font of the label widget to Purisa 10. | ||
+ | |||
+ | |||
+ | [[image: pygtk_faq_quotations.png | center]] | ||
+ | |||
+ | == System fonts == | ||
+ | The next code example shows all available fonts in a <b>TreeView</b> widget. | ||
+ | <source lang="python"> | ||
+ | #!/usr/bin/python | ||
+ | # ZetCode PyGTK tutorial | ||
+ | # | ||
+ | # This example lists all available | ||
+ | # fonts on a system in a TreeView widget | ||
+ | # | ||
+ | # author: jan bodnar | ||
+ | # website: zetcode.com | ||
+ | # last edited: February 2009 | ||
+ | |||
+ | import gtk | ||
+ | import pango | ||
+ | |||
+ | class PyApp(gtk.Window): | ||
+ | def __init__(self): | ||
+ | super(PyApp, self).__init__() | ||
+ | |||
+ | self.set_size_request(350, 250) | ||
+ | self.set_border_width(8) | ||
+ | self.connect("destroy", gtk.main_quit) | ||
+ | self.set_title("System fonts") | ||
+ | |||
+ | sw = gtk.ScrolledWindow() | ||
+ | sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) | ||
+ | sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) | ||
+ | |||
+ | context = self.create_pango_context() | ||
+ | self.fam = context.list_families() | ||
+ | |||
+ | store = self.create_model() | ||
+ | |||
+ | treeView = gtk.TreeView(store) | ||
+ | treeView.set_rules_hint(True) | ||
+ | sw.add(treeView) | ||
+ | |||
+ | self.create_column(treeView) | ||
+ | |||
+ | self.add(sw) | ||
+ | |||
+ | self.set_position(gtk.WIN_POS_CENTER) | ||
+ | self.show_all() | ||
+ | |||
+ | |||
+ | def create_column(self, treeView): | ||
+ | rendererText = gtk.CellRendererText() | ||
+ | column = gtk.TreeViewColumn("FontName", rendererText, text=0) | ||
+ | column.set_sort_column_id(0) | ||
+ | treeView.append_column(column) | ||
+ | |||
+ | def create_model(self): | ||
+ | store = gtk.ListStore(str) | ||
+ | |||
+ | for ff in self.fam: | ||
+ | store.append([ff.get_name()]) | ||
+ | |||
+ | return store | ||
+ | |||
+ | |||
+ | PyApp() | ||
+ | gtk.main() | ||
+ | </source> | ||
+ | |||
+ | The code example shows all available fonts on a system. | ||
+ | |||
+ | <source lang="python"> | ||
+ | context = self.create_pango_context() | ||
+ | </source> | ||
+ | |||
+ | This code line creates a pango context object. It contains global information about the rendering process of text. | ||
+ | |||
+ | <source lang="python"> | ||
+ | |||
+ | self.fam = context.list_families() | ||
+ | </source> | ||
+ | |||
+ | From the context object, we retrieve all available font families. | ||
+ | |||
+ | <source lang="python"> | ||
+ | for ff in self.fam: | ||
+ | store.append([ff.get_name()]) | ||
+ | </source> | ||
+ | |||
+ | During the model creation of the <b>TreeView</b> widget, we get all font names from the array of font families and put them into the list store. | ||
+ | |||
+ | [[image: pygtk_faq_systemfonts.png | center]] | ||
+ | |||
+ | == Unicode == | ||
+ | Pango is used to work with internationalized text. | ||
+ | <source lang="python"> | ||
+ | #!/usr/bin/python | ||
+ | # -*- coding: utf-8 -*- | ||
+ | # ZetCode PyGTK tutorial | ||
+ | # | ||
+ | # This example displays text | ||
+ | # in azbuka | ||
+ | # | ||
+ | # author: jan bodnar | ||
+ | # website: zetcode.com | ||
+ | # last edited: February 2009 | ||
+ | |||
+ | import gtk | ||
+ | import pango | ||
+ | |||
+ | obj = unicode(u'''Фёдор Михайлович Достоевский родился 30 октября (11 ноября) | ||
+ | 1821 года в Москве. Был вторым из 7 детей. Отец, Михаил Андреевич, | ||
+ | работал вгоспитале для бедных. Мать, Мария Фёдоровна | ||
+ | (в девичестве Нечаева), происходила из купеческого рода.''') | ||
+ | |||
+ | |||
+ | class PyApp(gtk.Window): | ||
+ | def __init__(self): | ||
+ | super(PyApp, self).__init__() | ||
+ | |||
+ | self.connect("destroy", gtk.main_quit) | ||
+ | self.set_title("Unicode") | ||
+ | |||
+ | label = gtk.Label(obj.encode('utf-8')) | ||
+ | |||
+ | fontdesc = pango.FontDescription("Purisa 10") | ||
+ | label.modify_font(fontdesc) | ||
+ | |||
+ | fix = gtk.Fixed() | ||
+ | |||
+ | fix.put(label, 5, 5) | ||
+ | |||
+ | self.add(fix) | ||
+ | self.set_position(gtk.WIN_POS_CENTER) | ||
+ | self.show_all() | ||
+ | |||
+ | PyApp() | ||
+ | gtk.main() | ||
+ | </source> | ||
+ | |||
+ | We show some text in azbuka. | ||
+ | |||
+ | <source lang="python"> | ||
+ | # -*- coding: utf-8 -*- | ||
+ | </source> | ||
+ | |||
+ | In order to work directly with internationalized text in the source code, we must provide this magic comment. Note, that it must be on the first or the second line. | ||
+ | |||
+ | <source lang="python"> | ||
+ | obj = unicode(u'''Фёдор Михайлович Достоевский родился 30 октября (11 ноября) | ||
+ | 1821 года в Москве. Был вторым из 7 детей. Отец, Михаил Андреевич, | ||
+ | работал вгоспитале для бедных. Мать, Мария Фёдоровна | ||
+ | (в девичестве Нечаева), происходила из купеческого рода.''') | ||
+ | </source> | ||
+ | |||
+ | This is text in azbuka. | ||
+ | |||
+ | <source lang="python"> | ||
+ | Label label = new Label(text); | ||
+ | </source> | ||
+ | |||
+ | We put encoded text into the label. | ||
+ | |||
+ | [[image: pygtk_faq_unicode.png | center]] | ||
+ | |||
+ | |||
+ | == Attributes == | ||
+ | Pango attribute is an attribute that applies to a section of text. | ||
+ | <source lang="python"> | ||
+ | #!/usr/bin/python | ||
+ | # ZetCode PyGTK tutorial | ||
+ | # | ||
+ | # In this program we work with | ||
+ | # pango attributes | ||
+ | # | ||
+ | # author: jan bodnar | ||
+ | # website: zetcode.com | ||
+ | # last edited: February 2009 | ||
+ | |||
+ | import gtk | ||
+ | import pango | ||
+ | |||
+ | text = "Valour fate kinship darkness" | ||
+ | |||
+ | class PyApp(gtk.Window): | ||
+ | def __init__(self): | ||
+ | super(PyApp, self).__init__() | ||
+ | |||
+ | self.connect("destroy", gtk.main_quit) | ||
+ | self.set_title("Attributes") | ||
+ | |||
+ | label = gtk.Label(text) | ||
+ | |||
+ | attr = pango.AttrList() | ||
+ | |||
+ | fg_color = pango.AttrForeground(65535, 0, 0, 0, 6) | ||
+ | underline = pango.AttrUnderline(pango.UNDERLINE_DOUBLE, 7, 11) | ||
+ | bg_color = pango.AttrBackground(40000, 40000, 40000, 12, 19) | ||
+ | strike = pango.AttrStrikethrough(True, 20, 29) | ||
+ | size = pango.AttrSize(30000, 0, -1) | ||
+ | |||
+ | attr.insert(fg_color) | ||
+ | attr.insert(underline) | ||
+ | attr.insert(bg_color) | ||
+ | attr.insert(size) | ||
+ | attr.insert(strike) | ||
+ | |||
+ | label.set_attributes(attr) | ||
+ | |||
+ | fix = gtk.Fixed() | ||
+ | |||
+ | fix.put(label, 5, 5) | ||
+ | |||
+ | self.add(fix) | ||
+ | self.set_position(gtk.WIN_POS_CENTER) | ||
+ | self.show_all() | ||
+ | |||
+ | PyApp() | ||
+ | gtk.main() | ||
+ | </source> | ||
+ | |||
+ | In the code example we show four different attributes applied | ||
+ | on the text. | ||
+ | |||
+ | <source lang="python"> | ||
+ | attr = pango.AttrList() | ||
+ | </source> | ||
+ | |||
+ | Pango attribute list is an object for holding attributes. | ||
+ | |||
+ | <source lang="python"> | ||
+ | fg_color = pango.AttrForeground(65535, 0, 0, 0, 6) | ||
+ | </source> | ||
+ | |||
+ | Here we create an attribute that will render text in red color. The first three parameters are the R, G, B values of a color. The last two parameters are the start and end indexes of the text, to which we apply this attribute. | ||
+ | |||
+ | <source lang="python"> | ||
+ | label.set_attributes(attr) | ||
+ | </source> | ||
+ | |||
+ | We set the list of attributes for the label. | ||
+ | |||
+ | [[image: pygtk_faq_attributes.png | center]] | ||
+ | |||
+ | In this chapter of the PyGTK programming library, we worked with pango library. | ||
+ | |||
+ | == Animated text == | ||
+ | The following example shows animated text on window. | ||
+ | <source lang="python"> | ||
+ | #!/usr/bin/python | ||
+ | # ZetCode PyGTK tutorial | ||
+ | # | ||
+ | # This example shows animated text | ||
+ | # | ||
+ | # author: jan bodnar | ||
+ | # website: zetcode.com | ||
+ | # last edited: February 2009 | ||
+ | |||
+ | import gtk | ||
+ | import glib | ||
+ | import pango | ||
+ | import math | ||
+ | |||
+ | |||
+ | class PyApp(gtk.Window): | ||
+ | def __init__(self): | ||
+ | super(PyApp, self).__init__() | ||
+ | |||
+ | self.connect("destroy", gtk.main_quit) | ||
+ | glib.timeout_add(160, self.on_timer) | ||
+ | |||
+ | self.count = 1 | ||
+ | |||
+ | self.set_border_width(10) | ||
+ | self.set_title("ZetCode") | ||
+ | |||
+ | self.label = gtk.Label("ZetCode") | ||
+ | |||
+ | fontdesc = pango.FontDescription("Serif Bold 30") | ||
+ | self.label.modify_font(fontdesc) | ||
+ | |||
+ | vbox = gtk.VBox(False, 0) | ||
+ | vbox.add(self.label) | ||
+ | |||
+ | self.add(vbox) | ||
+ | self.set_size_request(300, 250) | ||
+ | self.set_position(gtk.WIN_POS_CENTER) | ||
+ | self.show_all() | ||
+ | |||
+ | def on_timer(self): | ||
+ | attr = pango.AttrList() | ||
+ | self.count = self.count + 1 | ||
+ | |||
+ | for i in range(7): | ||
+ | r = pango.AttrRise(int(math.sin(self.count+i)*20)*pango.SCALE, i, i+1) | ||
+ | attr.insert(r) | ||
+ | |||
+ | self.label.set_attributes(attr) | ||
+ | return True | ||
+ | |||
+ | |||
+ | PyApp() | ||
+ | gtk.main() | ||
+ | </source> | ||
+ | |||
+ | In the above code example, we have a text in a label widget. By continuously changing its pango attributes, the text is being animated. | ||
+ | |||
+ | <source lang="python"> | ||
+ | self.label = gtk.Label("ZetCode") | ||
+ | |||
+ | fontdesc = pango.FontDescription("Serif Bold 30") | ||
+ | self.label.modify_font(fontdesc) | ||
+ | </source> | ||
+ | |||
+ | We create a label widget and modify its font. We choose a bit larger text for better visibility. | ||
+ | |||
+ | <source lang="python"> | ||
+ | vbox = gtk.VBox(False, 0) | ||
+ | vbox.add(self.label) | ||
+ | </source> | ||
+ | |||
+ | We put the label into the vertical box. This centers the label on the window. | ||
+ | |||
+ | The animation is performed inside the <b>on_timer()</b> method. | ||
+ | |||
+ | <source lang="python"> | ||
+ | for i in range(7): | ||
+ | r = pango.AttrRise(int(math.sin(self.count+i)*20)*pango.SCALE, i, i+1) | ||
+ | attr.insert(r) | ||
+ | </source> | ||
+ | |||
+ | We have seven characters in our text. We periodically change the pango <b>AttrRise</b> attribute for each character. The rise is based on the trigonometric sine function. The text movement follows the sine function graphed on the cartesian graph. | ||
+ | |||
+ | Also notice the <b>pango.SCALE</b> constant. The pango library has its own units. They differ from what is used by the widgets to draw graphics or text. We must multiply our numbers by this constant. | ||
+ | |||
+ | [[image: pygtk_faq_sine.png | center]] | ||
+ | |||
+ | == Using markup language == | ||
+ | We can change the attributes of the text using the built-in markup language. | ||
+ | <source lang="python"> | ||
+ | #!/usr/bin/python | ||
+ | # ZetCode PyGTK tutorial | ||
+ | # | ||
+ | # This example uses markup language | ||
+ | # to change attributes of the text | ||
+ | # | ||
+ | # author: jan bodnar | ||
+ | # website: zetcode.com | ||
+ | # last edited: February 2009 | ||
+ | |||
+ | import gtk | ||
+ | import pango | ||
+ | |||
+ | quote = "<span foreground='blue' size='19000'>The only victory over love is flight</span>" | ||
+ | |||
+ | |||
+ | class PyApp(gtk.Window): | ||
+ | def __init__(self): | ||
+ | super(PyApp, self).__init__() | ||
+ | |||
+ | self.set_title("Markup") | ||
+ | self.set_border_width(5) | ||
+ | self.connect("destroy", gtk.main_quit) | ||
+ | |||
+ | label = gtk.Label() | ||
+ | label.set_markup(quote) | ||
+ | |||
+ | vbox = gtk.VBox(False, 0) | ||
+ | vbox.add(label) | ||
+ | |||
+ | self.add(vbox) | ||
+ | self.set_position(gtk.WIN_POS_CENTER) | ||
+ | self.show_all() | ||
+ | |||
+ | PyApp() | ||
+ | gtk.main() | ||
+ | </source> | ||
+ | |||
+ | In the code example, we have a label. We change the it's text attributes with the markup language. | ||
+ | |||
+ | <source lang="python"> | ||
+ | quote = "<span foreground='blue' size='19000'>The only victory over love is flight</span>" | ||
+ | |||
+ | </source> | ||
+ | |||
+ | This is the text with the markup language. | ||
+ | |||
+ | <source lang="python"> | ||
+ | label = gtk.Label() | ||
+ | label.set_markup(quote) | ||
+ | </source> | ||
+ | |||
+ | We create a label widget and set a markup text for it. | ||
+ | |||
+ | [[image: pygtk_faq_markup.png | center]] | ||
+ | |||
+ | == Pango layout == | ||
+ | Pango layout is an object representing a paragraph of text with attributes. | ||
+ | <source lang="python"> | ||
+ | #!/usr/bin/python | ||
+ | # ZetCode PyGTK tutorial | ||
+ | # | ||
+ | # This example shows pango Layout | ||
+ | # in action | ||
+ | # | ||
+ | # author: jan bodnar | ||
+ | # website: zetcode.com | ||
+ | # last edited: February 2009 | ||
+ | |||
+ | import gtk | ||
+ | import pango | ||
+ | |||
+ | lyrics = """Meet you downstairs in the bar and heard | ||
+ | your rolled up sleeves and your skull t-shirt | ||
+ | You say why did you do it with him today? | ||
+ | and sniff me out like I was Tanqueray | ||
+ | |||
+ | cause you're my fella, my guy | ||
+ | hand me your stella and fly | ||
+ | by the time I'm out the door | ||
+ | you tear men down like Roger Moore | ||
+ | |||
+ | I cheated myself | ||
+ | like I knew I would | ||
+ | I told ya, I was trouble | ||
+ | you know that I'm no good""" | ||
+ | |||
+ | class Area(gtk.DrawingArea): | ||
+ | def __init__(self): | ||
+ | super(Area, self).__init__() | ||
+ | self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(16400, 16400, 16440)) | ||
+ | self.connect("expose_event", self.expose) | ||
+ | |||
+ | def expose(self, widget, event): | ||
+ | |||
+ | gc = self.get_style().fg_gc[gtk.STATE_NORMAL] | ||
+ | font_desc = pango.FontDescription('Sans 10') | ||
+ | |||
+ | layout = self.create_pango_layout(lyrics) | ||
+ | width, height = self.get_size_request() | ||
+ | |||
+ | attr = pango.AttrList() | ||
+ | |||
+ | fg_color = pango.AttrForeground(60535, 60535, 60535, 0, -1) | ||
+ | attr.insert(fg_color) | ||
+ | |||
+ | layout.set_width(pango.SCALE * self.allocation.width) | ||
+ | layout.set_spacing(pango.SCALE * 3) | ||
+ | layout.set_alignment(pango.ALIGN_CENTER) | ||
+ | layout.set_font_description(font_desc) | ||
+ | layout.set_attributes(attr) | ||
+ | |||
+ | self.window.draw_layout(gc, 0, 5, layout) | ||
+ | |||
+ | |||
+ | |||
+ | class PyApp(gtk.Window): | ||
+ | def __init__(self): | ||
+ | super(PyApp, self).__init__() | ||
+ | |||
+ | self.connect("destroy", gtk.main_quit) | ||
+ | self.set_title("You know I'm no Good") | ||
+ | |||
+ | self.add(Area()) | ||
+ | self.set_size_request(300, 300) | ||
+ | self.set_position(gtk.WIN_POS_CENTER) | ||
+ | self.show_all() | ||
+ | |||
+ | |||
+ | PyApp() | ||
+ | gtk.main() | ||
+ | </source> | ||
+ | |||
+ | In the previous examples, we were modifying text in existing widgets. Now we are going to draw the text using the pango layout on the <b>DrawingArea</b> widget. We will be drawing using the <b>Gdk</b> drawing tools. | ||
+ | |||
+ | <source lang="python"> | ||
+ | gc = self.get_style().fg_gc[gtk.STATE_NORMAL] | ||
+ | </source> | ||
+ | |||
+ | We get the graphics contex of the drawing area widget. | ||
+ | |||
+ | <source lang="python"> | ||
+ | layout = self.create_pango_layout(lyrics) | ||
+ | </source> | ||
+ | |||
+ | Here create the pango layout object. | ||
+ | |||
+ | <source lang="python"> | ||
+ | layout.set_width(pango.SCALE * self.allocation.width) | ||
+ | layout.set_spacing(pango.SCALE * 3) | ||
+ | layout.set_alignment(pango.ALIGN_CENTER) | ||
+ | layout.set_font_description(font_desc) | ||
+ | layout.set_attributes(attr) | ||
+ | </source> | ||
+ | |||
+ | We modify layout's width, spacing, alignment, font and set text attributes. | ||
+ | |||
+ | <source lang="python"> | ||
+ | self.window.draw_layout(gc, 0, 5, layout) | ||
+ | </source> | ||
+ | |||
+ | The layout is being drawn on the window. | ||
+ | |||
+ | [[image: pygtk_faq_layout.png | center]] | ||
+ | |||
+ | |||
+ | In this chapter of the PyGTK programming library, we further worked with pango library. | ||
+ | |||
+ | [[Категория:Python]] | ||
+ | [[Категория:GTK+]] |