Играем в Крестики-Нолики с Python и GTK

Предисловие


Новый блог GTK+ порадовал статьёй для начинающих и я решил попробовать что-то более простое, чем C++/C. Python оказался как нельзя кстати. Объём кода на Python для работы с GTK значительно меньше чем на C++, что не может не радовать.

PyGTK


PyGTK — биндинг библиотеки GTK для языка Python, PyGTK используется во многих открытых программах (например IM Gajim). Библиотека может быть очень интересна для Python программистов, поскольку проста в обращении и полностью скрывает реализацию GTK.

Под катом пример приложения.

Пример приложения


Для изучения PyGTK я решил написать простой пример — игру Крестики-Нолики.
Окно игры будет максимально простым — квадрат из кнопок 3x3.

Окно игры:
Окно игры Крестики-Нолики

Итак приступим к реализации. В программе есть пара классов: XO_Field и XO_Win, первый хранит информацию о поле, второй создаёт GUI для приложения и обрабатывает события.

Я использовал для примера модуль pygtk, установленный из пакетного менеджера в Ubuntu, на других системах стоит воспользоваться пакетами или python easy-install, а для Windows есть инсталлятор.

Используем модуль pygtk версии 2.0 или старше:
import pygtk
pygtk.require('2.0')
import gtk

Создадим простое окно, по закрытию которого будем прерывать и цикл событий GTK. Функция destroy будет приведена чуть позже.
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("destroy", self.destroy)
self.window.set_title("Крестики-Нолики.py!")
self.window.set_border_width(10)
self.window.set_size_request(400,400)

Для окна воспользуемся вертикальной компоновкой из трёх строк с горизонтальной.
Так кнопки будут расположены как раз в виде квадрата 3x3. Для каждой из кнопок добавляется обработчик события «clicked», синтаксис добавления очень похож на сигналы и слоты в Qt.

self.vbox = gtk.VBox(False,0)
self.window.add(self.vbox)
        
for i in range(3):
    box = gtk.HBox(False,0)
    self.boxes.append(box)
    for j in range(3):
        self.buttons[i].append(self.create_button(box))
        self.buttons[i][j].connect("clicked",self.on_btn_click,i,j)
    self.vbox.pack_start(box,True,True,0)
    box.show()

Функция, создающая кнопку:
def create_button(self,box):
    button = gtk.Button(self.field.chr)
    box.pack_start(button,True,True,0)
    button.show()
    return button

Запуск основного цикла событий GTK и уничтожение окна:
def main(self):
    gtk.main()

def destroy(self, widget, data=None):
    gtk.main_quit()

По нажатию на кнопки происходит установка знака в указанную позицию и переход хода к следующему игроку, если ещё не определён победитель. Если игра завершена, результат выводится в заголовок окна.

Сама игра в Крестики-Нолики и её реализация довольно тривиальна, ссылка на исходный код приведена ниже. Больший интерес представляет сам цикл работы приложения Python в связке с GTK, так например сборщик мусора при сборке ссылок на объекты GTK также вызывает деструкторы для них, поскольку элементы UI содержат много ссылок на ресурсы.

P.S.
Лучшим решением было бы использовать GtkTable (контейнер для выравнивания виджетов по сетке) с 3 строками и 3 столбцами, но как-то вспомнил о нём поздно.
Со временем API GTK обновляется, как было замечено в комментариях, есть уже биндинг для gtk 3. Стоит постепенно переходить на него, но не до конца ясен вопрос с поддержкой gtk 3 на платформах, отличных от linux.

Весь исходный код примера

Источники

  1. PyGTK на Wiki
  2. Сайт проекта PyGTK
  3. О компоновке и виджетах

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 13

    +5
    Похоже, что администрации стоит задуматься о разделении статей «по уровням».
    Все-таки, на хабре много новичков во всех областях. И такие статьи статьи с одной стороны будут полезные новичкам, а с другой будут сливаться участниками с более высоким уровнем.
      +4
      Думаю, для только что образовавшегося блога GTK посты с «азами» лишними не будут )
        +9
        Дак, посты вообще лишними не бывают (за исключением, когда они являются откровенным бредом). И я ничего против поста не имею. Но, мне кажется, что под утро автор со статьей будут слиты местными «гуру».
        Я про то, что если бы были какие-то метки, даже простейшие, как на demiart. То всем бы от этого было лучше. И это относится не к конкретной статье, а вообще к Хабру.
          +6
          Уговорили, обсудим в рабочие будни.
      +2
      PyGTK уже неактуален. Теперь используется PyGObject.
      readthedocs.org/docs/python-gtk-3-tutorial/en/latest/index.html
        0
        Я правильно понимаю, что это не будет работать на операционках, отличных от *nix? Месяц назад ни на windows, ни на OSX GTK3 для питона я даже из исходников собрать не смог :(.
          +1
          Разум подсказывает, что «должно работать везде», но практика говорит, что «ой, не факт». На счёт Windows точно не могу ничего сказать, так как не используется нигде. Даже проверить не смогу.
        0
        Для окна воспользуемся вертикальной компоновкой из трёх строк с горизонтальной.

        Месье знает толк в извращениях… Ладно, всё-равно молодец!
          0
          Под статьей стоит тег 'gkt'. Исправьте плиз.
            +3
            код примера с PyGTK выложили на paste.kde.org? Мило мило.

            Вообще когда виду код типа

            self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
            self.window.set_title("Крестики-Нолики.py!")
            self.window.set_border_width(10)
            self.vbox = gtk.VBox(False,0)
            self.window.add(self.vbox)


            Сразу представляю себе что кто-то так же целиком в JavaScript собирает HTML-странички типа
            div1=document.createElement('div');
            div0.appendChild(div1);
            div1.style.width = '10px';


            Это я к тому, что есть же Glade, есть GTK-xml или как он там… Это и более наглядно и быстрее в разработке и помогает разделять логику и представление.
              0
              >PyGTK используется во многих открытых программах (например IM Gajim).

              Который ЛЮТО тормозит. Вообще непонимаю смысл писать на Питоне гуй проги тяжелее, чем окошко настроек или какой-нибудь визард. В итоге получаем ТОРМОЗА и поедание памяти.
                0
                Ну, Eric или Spyder на PyQt субъективно очень быстро работают (хотя у них долгий первый запуск), хотя это вполне полноценные IDE c нормальным автокомплитом. Есть мнение, что проблема не в Питоне.
                  +1
                  Сравнивалась скорость работы gajim'а и qutim'а при помощи конфы, в которой сидело несколько ботов и пуляли 100500 сообщений, вот gajim слился просто безбожно.

              Only users with full accounts can post comments. Log in, please.