Pull to refresh

Введение в Ruby/Tk. Часть первая

Reading time 5 min
Views 10K
Доброго времени суток!

Введение


Заглянув сегодня в свой ToDo лист, я понял, что работы на сегодня у меня нет. Сидеть в интернете и читать новости целыми сутками тоже, знаете ли, ещё то удовольствие. Надо было чем-то заняться, а именно написать какое-либо приложение. На следующих выходных я хотел познакомить вас со связкой Ruby + Qt, но поскольку Qt биндинги я пока не установил мне пришлось искать замену. И я её нашёл. Т.к. вместе с Ruby поставляется Tk, то именно на него и пал мой выбор.

Знакомимся с пациентом


Ф.И.О: Давыденко Михаил Юрьевич
Место рождения:

На самом деле, речь пойдет не обо мне, а о Tk.
Tk (от англ. Toolkit — «набор инструментов», «инструментарий») — кроссплатформенная библиотека базовых элементов графического интерфейса, распространяемая с открытыми исходными текстами.

Врач уже здесь


Ruby (от англ. Ruby — «Рубин») — динамический, рефлективный, интерпретируемый высокоуровневый язык программирования для быстрого и удобного объектно-ориентированного программирования. Язык обладает независимой от операционной системы реализацией многопоточности, строгой динамической типизацией, сборщиком мусора и многими другими возможностями. В общем и целом то, что нам сейчас нужно.

Разомнём пальцы


А именно напишем Hello World. Куда же мы без него?
Его код будет выглядеть примерно так:
require 'tk'
app = TkRoot.new {
     title "Hello Tk!"; padx 50; pady 15
}
TkLabel.new(app) {
     text "Hello, World!"
     pack { padx 100; pady 100; side "left" }
}
Tk.mainloop


Разбор полётов


Теперь давайте подробно разберёмся в том, что есть что.

Сначала мы импортировали библиотеку для работы с оной:
require 'tk'

Далее мы создали новое окно с заголовком Hello Tk!, высотой равной 50 пикселям и шириной в 15 пикселей:
app = TkRoot.new {
     title "Hello Tk!"; padx 50; pady 15
}

После чего создали надпись с текстом Hello World! с координатами 100x100:
TkLabel.new(app) {
     text "Hello, World!"
     pack { padx 100; pady 100; side "left" }
}

Здесь мы встретили незнакомое нам pack. Что же это такое?
pack является упаковщиком, который занимается расположением элементов (в данном случае это виджет Label) в родительском окне. Также существует ещё два упаковщика:
  • grid, который размещает виджеты в сетке. Данный упаковщик будет полезен, например, для составления таблицы или кнопок для калькулятора, который мы с вами обязательно напишем, но чуть позже;
  • place, который позволяет размещать виджеты в указанных координатах, с указанными нами размерами.

А, совсем забыл, вот, что у нас получилось. Получилось же?



События


Теперь я хотел бы затронуть тему отловки событий. Будь то нажатие кнопки или же навод курсора на какой-либо из виджетов. В Tk существует несколько типовых видов событий, а именно восемь! Вот они:
  • "1" или "ButtonPress-1", обозначающие, что виджет был кликнут левой кнопкой мыши;
  • "Enter", когда курсор наведён на наш виджет;
  • "Leave" — курсор был убран с нашего виджета (работает лишь после "Enter";
  • "Double-1" — был произведён двойной клик;
  • "B3-Motion" — произведено перемещение курсора, путём нажатия правой кнопки мыши, с одной позиции на другую;
  • "Control-ButtonPress-3" — правая кнопка мыши была нажата вместе с Ctrl;
  • "Alt-ButtonPress-1" — было произведено нажатие левой кнопки мыши вместе с Alt.

Мною были переведены именно типы событий, а не сами события. Говоря это, я имею ввиду, что мы можем использовать, как событие "ButtonPress-1" (нажатие левой кнопки мыши), так и "ButtonRelease-1" (отпускаем левую кнопку мыши). Так же, стоит отметь, что мы можем использовать две кнопки мыши (левую и правую). Например: "ButtonPress-1" (левая) и "ButtonPress-2" (правая).

Вот, собственно, и все доступные нам для перехвата события.

Ловить событие можно так:
wdgt.bind('ButtonPress-1') { puts "LBM: I was pressed..." }


Или так:
wdgt.bind('Control-ButtonPress-3', proc { puts "RBM + Ctrl: We was clicked..." })


А ещё внутри объявления самого виджета. Вот так:
wdgt = TkButton.new(app) {
     text "Click me!"
     command proc { puts "Button of nowhere: I was clicked..." }
}


Давайте закрепим наши знания на практике и напишем вот такую вот программулину:
require 'tk'
app = TkRoot.new {
     title "Hello Tk!"; padx 50; pady 15
}
but = TkButton.new(app) {
     text "Hello, World!"
     pack { padx 100; pady 100; side "left" }
}
but.bind("Enter", proc { but.text "Welcome!" })
but.bind("Leave", proc { but.text "Bye!" })
Tk.mainloop


При запуске ничего нового для себя мы не обнаружим.


Пока не подведём курсор к нашей кнопке. Вот, что у нас должно получиться:


Теперь отведём курсор и увидим, что кнопка с нами попрощалась:


Меню пожалуйста


Теперь я предлагаю закрепить наши знания по отловке событий и познакомиться с новым для нас виджетом Menu. Цель данного приложения будет заключаться в том, что мы должны выбрать любимый для нас язык программирования в меню. Далее я приведу код с вложенными комментариями. Думаю, понимание кода не вызовет у вас каких-либо трудностей. Итак, вот он:
require 'tk' # импортируем библиотеку

app = TkRoot.new { # создаём окно
     title "Hello Tk!"; padx 50; pady 15 # с нужными нам свойствами
}

lbl = TkLabel.new(app) { # создаём надпись
     text "Something wasn't clicked yet..." # с таким вот текстом
     pack { padx 100; pady 100; side "left" } # с такими координатами
}
java_clicked = Proc.new { # ловим клик "Java" в меню
     lbl.text "Java was liked..."
}
cs_clicked = Proc.new { # ловим клик "C#" в меню
     lbl.text "C# was liked..."
}
cpp_clicked = Proc.new { # ловим клик "C++" в меню
     lbl.text "C++ was liked..."
}
py_clicked = Proc.new { # ловим клик "Python" в меню
     lbl.text "Python was liked..."
}
rb_clicked = Proc.new { # ловим клик "Ruby" в меню
     lbl.text "Ruby was liked..."
}

menu = TkMenu.new(app) # создаём меню

menu.add('command', 'label' => "Java", 'command' => java_clicked) # создаём кнопку "Java"
menu.add('command', 'label' => "C#", 'command' => cs_clicked) # создаём кнопку "C#"
menu.add('separator') # создаём разделитель
menu.add('command', 'label' => "C++", 'command' => cpp_clicked) # создаём кнопку "C++"
menu.add('separator') # создаём разделитель
menu.add('command', 'label' => "Python", 'command' => py_clicked) # создаём кнопку "Python"
menu.add('command', 'label' => "Ruby", 'command' => rb_clicked) # создаём кнопку "Ruby"
bar = TkMenu.new # создаём бар для нашего меню
bar.add('cascade', 'menu' => menu, 'label' => "Click me, I want you!") # добавляем меню в бар
app.menu(bar) # указываем приложению на бар нашего меню
Tk.mainloop # и запускаем приложение, а почему бы и нет?

Действительно, пора запустить нашу программу. Собственно, вот:


Теперь откроем наше меню и кликнем по «Java». Вот, что мы увидим:


Заключение


Вот и всё на сегодня. Целью данного топика я ставил ознакомление вас с графической библиотекой Tk, которое, по моему мнению прошло успешно, хоть немного и поверхностно.

P.S. На следующих выходных мы с вами углубимся в изучение типичных и специфичных свойств виджетов в Tk, узнаем какие же виджеты имеются в Tk и закрепим наши знания путём написания Jabber-клиента, который был написан мною за 30 минут.

До скорых встреч!

Используемые материалы:
Ruby — Википедия
Tk — Википедия
Ruby/TK Guide

Также, я хотел бы выразить огромную благодарность моему хабрадругу t3ns0r за его Введение в Tkinter.
Tags:
Hubs:
+30
Comments 42
Comments Comments 42

Articles