Pull to refresh

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

Reading time2 min
Views24K

Предисловие


Новый блог 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. О компоновке и виджетах
Tags:
Hubs:
Total votes 37: ↑35 and ↓2+33
Comments13

Articles