<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.linuxformat.ru/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF131%3AClutter</id>
		<title>LXF131:Clutter - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF131%3AClutter"/>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF131:Clutter&amp;action=history"/>
		<updated>2026-05-13T13:37:49Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.19.20+dfsg-0+deb7u3</generator>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/index.php?title=LXF131:Clutter&amp;diff=11940&amp;oldid=prev</id>
		<title>Crazy Rebel: викификация, оформление, иллюстрация</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF131:Clutter&amp;diff=11940&amp;oldid=prev"/>
				<updated>2011-04-25T11:08:35Z</updated>
		
		<summary type="html">&lt;p&gt;викификация, оформление, иллюстрация&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''''Python''''' Настоящие задачи, чтобы вы поупражнялись в кодировании&lt;br /&gt;
&lt;br /&gt;
===''Python'': Рисуем с Clutter===&lt;br /&gt;
&lt;br /&gt;
{{Цикл/Python}}&lt;br /&gt;
&lt;br /&gt;
: ''Clutter'' предоставляет интерфейс, но, опираясь на свой опыт в графике, '''Ник Вейч''' добавит к нему мощь ''Cairo'' и создаст сетевые часы.&lt;br /&gt;
&lt;br /&gt;
Мы уже видели, как создавать в ''Clutter'' простые объекты, размещать их на экране и даже анимировать. Но пока мы создавали при помощи ''Clutter'' одни прямоугольнички. Эй! А как же другие формы и поверхности? Не-е, только не в ''Clutter''. Но голь на выдумки хитра: ''Clutter'' запряг вместо себя библиотеки ''Cairo''. Они содержат дюжину операций рисования в текстурах, и мы можем создать контекст ''Cairo'' и воспользоваться ими. Когда ''Cairo'' выполнит сложную часть, ''Clutter'' применит результат, как любую другую текстуру.&lt;br /&gt;
&lt;br /&gt;
В ранних версиях ''Clutter'' поддержка ''Cairo'' была реализована в виде встраиваемого модуля. Теперь это часть основного кода ''Clutter'', и нам не придется импортировать какие-либо специальные библиотеки – хотя для работы с контекстами ''Cairo'' потребуется ''Python''-модуль ''Cairo''. Откройте интерактивную оболочку ''Python'', введя ''python'' в командной строке, и наберите следующее:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import clutter&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import cairo&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import math&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если вы планируете работать с окружностями, дугами и так далее, имеет смысл импортировать модуль ''Math'' из стандартного комплекта ''Python'': в нем имеется константа пи ('''math.pi''') и методы для преобразования радиан в градусы и обратно. Далее выполним стандартный ритуал настройки сцены ''Clutter'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage = clutter.Stage()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_size(500,500)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; blue =clutter.Color(0,0,255,255)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_color(blue)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если вы следили за серией уроков по ''Clutter'', то понимаете, что это обычные действия, выполняемые при подготовке сцены. Теперь создадим нашего актера.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; cairoactor=clutter.CairoTexture(50,50)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; cairoactor.set_position(225,225)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь генерируется специальный актер, получающий текстуру из ''Cairo'', и мы размещаем его слева от центра нашей сцены, с учетом размера круга. А теперь нарисуем объект.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context=cairoactor.cairo_create()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.set_operator(cairo.OPERATOR_OVER)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.set_source_rgb(1,1,0)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.arc(25,25,20,0, 2*math.pi)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.close_path()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.fill()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объект '''context''', созданный нами здесь, на самом деле является измененным объектом ''Cairo'' и наследует все полезные методы ''Cairo''. Прежде чем начинать любые операции рисования, надо настроить режим рисования. Чаще всего мы будем использовать операцию '''OVER''', которая рисует поверх всего, что уже имеется в текстуре. '''Set_source_rgb()''' устанавливает цвет пера для будущих операций. Затем изобразим наш круг.&lt;br /&gt;
&lt;br /&gt;
Круг, в терминах ''Cairo'', это просто дуга, простирающаяся на 360° (или 2π, поскольку ''Cairo'' измеряет углы в радианах). Для этого метода мы должны указать координаты '''X''' и '''Y''' центральной точки, затем радиус дуги, а также начальный и конечный углы в радианах. Мы указали от '''0''' до '''2*math.pi''', то есть 360°.&lt;br /&gt;
&lt;br /&gt;
Заливаемый контур должны быть замкнутым. Вы можете подумать, что он уже замкнут – а вот и нет. По мнению ''Cairo'', это пока просто контур, который начинается и заканчивается в одной точке.&lt;br /&gt;
&lt;br /&gt;
Чтобы замкнуть его, следует вызвать метод '''close_path()''', а уж потом можно закрашивать. Метод '''fill()''' пытается заполнить текущую активную фигуру. Если же мы хотим изобразить контур фигуры (то есть окружность, а не круг), следует использовать метод '''stroke()'''.&lt;br /&gt;
&lt;br /&gt;
Создав круг, отобразим этот объект, добавим его в сцену и затем отрисуем все вместе:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; cairoactor.show()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.add(cairoactor)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.show_all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ну и где круг?! Мы же ввели команды рисования, а затем добавили актера на сцену! Ответ в том, что мы покамест в контексте ''Cairo''. Модуль ''Cairo'' не приступит к выводу изображения вашей текстуры, пока вы его не удалите. Да, это звучит странно, но по пробуйте:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; del context&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Что такое Cairo?===&lt;br /&gt;
&lt;br /&gt;
Не считая родного города пирамид, ''Cairo'' – это название графического инструментария, созданного Карлом Вортом [Carl Worth] и другими. Мы брали у его разработчиков интервью в [[LXF111:Interview|LXF111]].&lt;br /&gt;
&lt;br /&gt;
Целью ''Cairo'' было создание стандартного набора графических инструментов для выполнения насущных задач быстро и просто. Во многих приложениях, где надо отрисовывать графику, реализуются свои собственные алгоритмы – в уверенности, что они будут быстрее, лучше и проще в сопровождении; но часто это не так.&lt;br /&gt;
&lt;br /&gt;
''Cairo'' кросс-платформенный, интегрируется с нескольким графическими оболочками и поддерживает графическое ускорение. Дополнительную информацию см. на http://www.cairographics.org.&lt;br /&gt;
&lt;br /&gt;
===Как это работает===&lt;br /&gt;
&lt;br /&gt;
Как по волшебству, круг появился! Запутаться немудрено, но представьте себе такую модель. Пусть ''Clutter'' – директор картинной галереи. Галерея – то место, где объекты отображаются; но создаются они в другом месте. Галерея (''Clutter'') берет холст (текстуру) и отправляет его художнику (''Cairo''). Затем галерея просит художника нарисовать картину в соответствии с инструкциями (вызовы в контексте). Но чтобы галерея могла отобразить ее, художник должен отправить картину обратно (удалить из контекста). Если галерея когда-либо захочет изменить картину, она может просто вернуть ее художнику (создать для объекта новый контекст). Так что воспринимайте удаление объекта контекста как завершение контракта.&lt;br /&gt;
&lt;br /&gt;
Есть и другие моменты, о которых следует знать при работе с кодом ''Clutter/Cairo'', особенно в ''Python''. Текстура обновляется, когда контекст выходит за границы области видимости (в коде). В предыдущем примере это происходило потому, что мы явным образом удаляли его, а ''Python'' очень хорошо очищает память, которая больше не требуется. Также, контекст может выйти из области видимости и автоматически удалиться, если, например, это локальная переменная в завершившейся функции. За этим необходимо следить. Некоторые программисты используют эту особенность, чтобы прибирать за собой – ведь если сборщик мусора ''Python'' желает сам заботиться об удалении ваших объектов, то чего напрягаться? Но иногда наличие явных удалений облегчает понимание кода. К тому же для некоторых библиотек, несмотря на то, что ''Python'' освобождает память, модуль может не освободить дескриптор контекста, что вызовет проблемы.&lt;br /&gt;
&lt;br /&gt;
Большинство операторов рисования ''Cairo'' имеют альтернативы, использующие относительные координаты вместо абсолютных. И это замечательно, когда объект рисуется и точно не известно, где он начинается, или известно лишь, что необходимо перейти в определенном направлении на заданное расстояние (к сожалению, сложение векторов среди умений ''Cairo'' не значится).&lt;br /&gt;
&lt;br /&gt;
Чтобы разобраться со всем этим, изобразим треугольник. Помните, что координаты, передаваемые методам '''context''', задаются относительно текстуры ''Cairo'', а не сцены.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import clutter&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import cairo&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage = clutter.Stage()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_size(500,500)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; blue =clutter.Color(0,0,255,255) &lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_color(blue)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; cairoactor=clutter.CairoTexture(50,50)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; cairoactor.set_position(225,225)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context=cairoactor.cairo_create()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.set_operator(cairo.OPERATOR_OVER)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.set_line_width(5)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.set_source_rgb(1,0,0)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.move_to(3,3)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.line_to(47,3)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.rel_line_to(-22,44)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.close_path()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.stroke_preserve()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.set_source_rgb(0,1,0)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; context.fill()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; del context&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; cairoactor.show()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.add(cairoactor)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.show_all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF131_78_1.jpg|300px]]  Вызовы контекста и их действие. Синим цветом показан контур.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Поскольку на сей раз мы применили операцию '''stroke''', необходимо установить толщину линии. Кроме того, мы использовали метод '''stroke_preserve()'''. Опцию '''preserve''' имеют большинство методов рисования. Обычно их вызов удаляет активный контур в ходе стандартной процедуры очистки текстуры. Если требуется ис пользовать контур вновь, сохраните его для следующей операции опцией '''preserve'''. Если запутались с координатами, смотрите рисунок.&lt;br /&gt;
&lt;br /&gt;
===Рисуем часы===&lt;br /&gt;
&lt;br /&gt;
Для наших часов нарисуем циферблат при помощи объектов ''Cairo'', затем создадим несколько текстур для стрелок. Стрелки можно сделать любой сложности. В нашем проекте мы применим вытянутые ромбы, поскольку сложные стрелки требуют больше кода для рисования и отнимают место на объяснение происходящего.&lt;br /&gt;
&lt;br /&gt;
Циферблат часов – это текстура, но в ней будут повторяющиеся по кругу объекты, обозначающие точки циферблата. Можно было заняться математикой и в цикле разместить каждую цифру в виде отдельной текстуры. Но это утомительно и занимает много места; вместо этого создадим их программно.&lt;br /&gt;
'&lt;br /&gt;
Облегчим себе жизнь некоторыми преобразованиями из ''Cairo''. Метод '''translate()''' смещает центральную ось контекста области рисования, а '''rotate()''' вращает ее. Скомбинировав их, мы можем повторно рисовать один и тот же круг и сдвигать контекст между отрисовками – воспринимайте это как печать на листе бумаги, который сдвигается перед очередным оттиском. Штамп опускается на то же место, а поверхность смещается. Мы разбили код на разделы, чтобы вы могли видеть это в действии, начиная с '''def_drawface'''.&lt;br /&gt;
&lt;br /&gt;
===Запускаем часы===&lt;br /&gt;
&lt;br /&gt;
Данный код создает объект класса '''clock''', содержащий все необходимые причиндалы. Процедура '''init''' настраивает сцену, вызывает функции для отрисовки необходимых текстур и реализует шкалу времени. Это та шкала времени, что заставляет наши часы тикать – она обновляет их каждые 1000 мс. Отметим, что метод '''update''' обращается к системному времени, не полагаясь только на прерывания, так что часы всегда синхронизированы с системными.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Заголовок=Скорая помощь|Содержание=Для установки модулей ''Python'' существует простой инструмент подназванием ''easy_install'', обычно это часть пакета '''python-setuptools'''. Имеется также ''Pip'', установщик, который работает как ''Yum'' или ''apt-get''.|Ширина=200px}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 import clutter&lt;br /&gt;
 import cairo&lt;br /&gt;
 import math&lt;br /&gt;
 import time&lt;br /&gt;
 class clock:&lt;br /&gt;
   def __init__ (self):&lt;br /&gt;
     self.stage = clutter.Stage()&lt;br /&gt;
     self.stage.set_color(clutter.Color(0, 0, 0, 255))&lt;br /&gt;
     self.stage.set_size(500, 500)&lt;br /&gt;
     self.stage.set_title(‘LXF Atomic Clock’)&lt;br /&gt;
     self.stage.connect(‘key-press-event’, self.parseKeyPress)&lt;br /&gt;
     self.stage.connect(“destroy”, clutter.main_quit)&lt;br /&gt;
     self.drawface()&lt;br /&gt;
     self.drawhands()&lt;br /&gt;
     self.stage.show_all()&lt;br /&gt;
     self.t=clutter.Timeline()&lt;br /&gt;
     self.t.set_duration(1000)&lt;br /&gt;
     self.t.set_loop(True)&lt;br /&gt;
     self.t.connect(‘completed’, self.update)&lt;br /&gt;
     self.t.start()&lt;br /&gt;
     clutter.main()&lt;br /&gt;
   def parseKeyPress(self, stage, event):&lt;br /&gt;
     # Выполняем действия по на жатию клавиши пользователем&lt;br /&gt;
     if event.keyval == clutter.keysyms.q:&lt;br /&gt;
        # Ес ли на жата клавиша “q” - вы ходим из при ложения&lt;br /&gt;
        clutter.main_quit()&lt;br /&gt;
   def drawface(self):&lt;br /&gt;
     self.face=clutter.CairoTexture(500,500)&lt;br /&gt;
     self.face.set_position(0,0)&lt;br /&gt;
     context=self.face.cairo_create()&lt;br /&gt;
     context.set_operator(cairo.OPERATOR_OVER)&lt;br /&gt;
     context.set_source_rgb(1,1,0)&lt;br /&gt;
     context.translate(250, 250)&lt;br /&gt;
     for a in range(12):&lt;br /&gt;
        context.arc(0,230,12,0, 2*math.pi)&lt;br /&gt;
        context.close_path()&lt;br /&gt;
        context.fill()&lt;br /&gt;
        context.rotate(2*math.pi/12)&lt;br /&gt;
    for a in range(4):&lt;br /&gt;
        context.arc(0,230,18,0, 2*math.pi)&lt;br /&gt;
        context.close_path()&lt;br /&gt;
        context.fill()&lt;br /&gt;
        context.rotate(2*math.pi/4)&lt;br /&gt;
     del context&lt;br /&gt;
     self.face.show_all()&lt;br /&gt;
     self.stage.add(self.face)&lt;br /&gt;
   def drawhands(self):&lt;br /&gt;
     self.hhand=clutter.CairoTexture(30,220)&lt;br /&gt;
     self.hhand.set_position(235,250)&lt;br /&gt;
     context=self.hhand.cairo_create()&lt;br /&gt;
     context.set_operator(cairo.OPERATOR_OVER)&lt;br /&gt;
     context.set_source_rgb(1,1,1)&lt;br /&gt;
     context.set_line_width(2)&lt;br /&gt;
      context.move_to(0,0)&lt;br /&gt;
      context.line_to(30,0)&lt;br /&gt;
      context.line_to(25,120)&lt;br /&gt;
      context.line_to(5, 120)&lt;br /&gt;
      context.close_path()&lt;br /&gt;
      context.stroke_preserve()&lt;br /&gt;
      context.set_source_rgb(0,1,0)&lt;br /&gt;
      context.fill()&lt;br /&gt;
      del context&lt;br /&gt;
      self.hhand.show_all()&lt;br /&gt;
      self.stage.add(self.hhand)&lt;br /&gt;
      # минут ная стрелка&lt;br /&gt;
      self.mhand=clutter.CairoTexture(16,220)&lt;br /&gt;
      self.mhand.set_position(242,250)&lt;br /&gt;
      context=self.mhand.cairo_create()&lt;br /&gt;
      context.set_operator(cairo.OPERATOR_OVER)&lt;br /&gt;
      context.set_source_rgb(1,1,1)&lt;br /&gt;
      context.set_line_width(2)&lt;br /&gt;
      context.move_to(0,0)&lt;br /&gt;
      context.line_to(16,0)&lt;br /&gt;
      context.line_to(14,160)&lt;br /&gt;
      context.line_to(2, 160)&lt;br /&gt;
      context.close_path()&lt;br /&gt;
      context.stroke_preserve()&lt;br /&gt;
      context.set_source_rgb(0,0,1)&lt;br /&gt;
      context.fill()&lt;br /&gt;
      del context&lt;br /&gt;
      self.mhand.show_all()&lt;br /&gt;
      self.stage.add(self.mhand)&lt;br /&gt;
      # часовая стрелка&lt;br /&gt;
      self.shand=clutter.CairoTexture(9,225)&lt;br /&gt;
      self.shand.set_position(246,250)&lt;br /&gt;
      context=self.shand.cairo_create()&lt;br /&gt;
      context.set_operator(cairo.OPERATOR_OVER)&lt;br /&gt;
      context.set_source_rgb(1,1,1)&lt;br /&gt;
      context.set_line_width(1)&lt;br /&gt;
      context.move_to(0,0)&lt;br /&gt;
      context.line_to(9,0)&lt;br /&gt;
      context.line_to(5,225)&lt;br /&gt;
      context.close_path()&lt;br /&gt;
      context.stroke_preserve()&lt;br /&gt;
      context.set_source_rgb(1,0,0)&lt;br /&gt;
      context.fill()&lt;br /&gt;
      del context&lt;br /&gt;
      self.shand.show_all()&lt;br /&gt;
      self.stage.add(self.shand)&lt;br /&gt;
    def update(self, signal):&lt;br /&gt;
      z=time.gmtime()&lt;br /&gt;
      hangle=30*z.tm_hour+(.5*z.tm_min)-180&lt;br /&gt;
      mangle=6*z.tm_min+(.1*z.tm_sec)-180&lt;br /&gt;
      sangle=6*z.tm_sec-180&lt;br /&gt;
      self.hhand.set_rotation(clutter.Z_AXIS, hangle, 15, 0, 0)&lt;br /&gt;
      self.mhand.set_rotation(clutter.Z_AXIS, mangle, 8, 0, 0)&lt;br /&gt;
      self.shand.set_rotation(clutter.Z_AXIS, sangle, 5, 0, 0)&lt;br /&gt;
 if __name__ == ‘__main__’:&lt;br /&gt;
    x=clock()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Львиная доля кода уйдет на стрелки часов, ведь для каждой черточки нужна своя линия. Можно сделать текстуры сколь угодно сложными, если, конечно, не жаль времени на написание рисующего их кода.&lt;br /&gt;
&lt;br /&gt;
Изначально мы собирались корректировать системное время при помощи часов NTP в Интернете. Увы, это оказалось малость непрактично – в современных дистрибутивах настроить время из скрипта ''Python'' не так-то просто: обычно необходимы привилегии root, а давать их пользовательскому сценарию не здорово!&lt;br /&gt;
&lt;br /&gt;
Поэкспериментируем с этой идеей: например, можно периодически получать время с сервера NTP. Шкала времени ''Clutter'' может использоваться как прерывание, генерируемое, скажем, каждый час. Используя модуль ''Python'' '''ntplib''' (http://pypi.python.org/pypi/ntplib), можно сравнить системное время с «реальным» и получить смещение, которое будет применено к часам после очередного вызова метода '''update()'''. Вы можете считать свои системные часы очень точными, но они быстро наработают отклонение, особенно на мобильных устройствах. Вот как работает механизм смещения:&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF131_79_1.jpg|300px]] Наши собственные часы — показывают время в Трамптоне или там, где вы находитесь.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def ntpcheck(self, signal):&lt;br /&gt;
  client=ntplib.NTPClient()&lt;br /&gt;
  response=client.request(‘europe.pool.ntp.org’,version=3)&lt;br /&gt;
  realtime= time.gmtime(response.tx_time)&lt;br /&gt;
  systime=time.gmtime()&lt;br /&gt;
  self.offset=(realtime.tm_hour-systime.tm_hour,realtime.tm_min-systime.tm_min,realtime.tm_sec-systime.tm_sec)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Другое возможное дополнение – анимация хода часов. Если честно, они передвигаются на такие короткие расстояния, что многие люди не заметят разницы; но было бы здорово применить одну из «прыгающих» анимаций для эмуляции перемещения стрелки, перескакивающей на новое место, как в старинных часах.&lt;br /&gt;
&lt;br /&gt;
Однако на самом деле наш урок был об использовании объектов ''Cairo''. На сайте ''Cairo'' можно найти куда больше документации о режимах и методах рисования. Вероятно, во многих случаях проще создать текстуру в виде файла и загружать ее при запуске приложения. Но для простых текстур приятно иметь возможность получить приложение, создающее их, и это необходимо для динамических изображений, вроде графиков.&lt;br /&gt;
&lt;br /&gt;
===Важное замечание о версиях===&lt;br /&gt;
&lt;br /&gt;
Наш урок основан на релизе 1.0 библиотеки ''Clutter'' и 0.98 – модуля ''PyClutter''. Более поздние версии поладят с кодом нашего урока, а более ранние – не факт: кроме всего прочего, структура пространства имен в ''PyClutter'' несколько раз менялась, как и иерархия объектов ''Clutter''.&lt;br /&gt;
&lt;br /&gt;
Всегда желательно по возможности брать библиотеку ''Clutter'' и модуль ''Python'' из репозитория вашего дистрибутива, если там достаточно новые версии.&lt;/div&gt;</summary>
		<author><name>Crazy Rebel</name></author>	</entry>

	</feed>