суботу, 12 травня 2012 р.

Введення в QtRuby

Ця стаття є введенням в програмування графічного інтерфейсу користувача(GUI) з використанням бібліотеки Qt, мови Ruby, і qt4-qtruby.

Якщо ви раніше ніколи не користувалися Qt, рекомендую почитати документ Як вивчати Qt. Не забувайте, що, як і більшість статей про Qt, ця сильно орієнтована на C++.

Найкращий спосіб почати програмувати з QtRuby це ознайомитися з прикладами коду, які знаходяться в директорії qtruby/examples.

Для початку розімнемо пальці. А саме напишемо Hello World. Куди ж ми без нього? Він містить тільки необхідний мінімум, що отримати робочий Qt додаток.
# -*- encoding: utf-8 -*-

require 'Qt'

app = Qt::Application.new(ARGV)
hello = Qt::PushButton.new("Hello World!")
hello.resize(100, 30)
hello.show
app.exec


QtRuby майже повністю охоплює Qt API. Але і має деякі особливості:
  • Властивості
    'fooBar = 5' є синонімом 'setFooBar(5)'
  • Предикати
    'if foo?' є синонімом для 'if isFoo()' або 'if hasFoo()'
  • Якщо ви надаєте перевагу underscope-стилю іменування методів, можете використувавати його замість lowerCamelCase. Будь-який знак підреслення в імені методу видаляється, а наступний символ капіталізується. Наприклад, ви можете використрвувати будь-яку з цих двох форм для виклику одного й того ж методу:
    create_standard_status_bar_action()
    createStandardStatusBarAction()
    
  • Сигнали і слоти оголошуються, як список рядків, наприклад:
    slots 'setColor(QColor)', 'slotLoad(const QString&)'..
    signals 'clicked()'..
    
    Якщо слот або сигнал не мають аргументів вони також можуть бути оголошені як:
    slots :click, :toggle
    signals :clicked
    
    Підключення слотів і сигналів здійснюється наступним чином:
    Qt::Object.connect @button, SIGNAL("clicked()"), self, SLOT("quit()")
    
  • Ви можете викликати конструктори у традиційному стилі:
    quit = Qt::PushButton.new("Quit", self, "quit")
    
    Або передавати блок, який викликатиметься у контексті створеного екземпляра:
    w = MyWidget.new { setCaption("foobar") }
    
    Також ви можете передати аргумент в блок:
    w = MyWidget.new { |widget| widget.set_caption "foobar" }
    
  • Всі віртуальні методи можуть бути перевизначені, а не тільки обробники подій.
  • Ви можете викликати всі публічні і захищені методи Qt.

Прийшов час вдосконалити наш Hello World. Натиснувши на кнопку, програма завершить роботу належним чином. Також змінимо шрифт за замовчуванням.
# -*- encoding: utf-8 -*-

require 'Qt'

app = Qt::Application.new(ARGV)
quit = Qt::PushButton.new("Quit")
quit.resize(75, 30)
quit.set_font(Qt::Font.new('Times', 18, Qt::Font::Bold))

Qt::Object.connect(quit, SIGNAL('clicked()'), app, SLOT('quit()'))
quit.show
app.exec

Розберемо нашу програму рядок за рядком.
require 'Qt'
Цей рядок завантажує розширення QtRuby.

app = Qt::Application.new(ARGV)
Кожен додаток повинен створювати екземпляр класу Qt::Application. Дуже важливо, щоб об’єкт Qt::Application був створений до того, як буде використана будь-яка інша частина Qt. ARGV - список аргументів командного рядка.

quit = Qt::PushButton.new("Quit")
Створюємо кнопку з надписом "Quit". Так як ми не визначили батьківське вікно(в якості другого аргументу в конструкторі Qt::PushButton) для віджета, кнопка і буде вікном, з власною рамкою і заголовком.

quit.resize(75, 30)
Встановлюємо розміри кнопки: 75 пікселів в ширину і 30 пікселів у висоту.

quit.set_font(Qt::Font.new('Times', 18, Qt::Font::Bold))
Тут ми вибираємо шрифт для кнопки: розмір 18 точок, жирний з сімейства Times.

Qt::Object.connect(quit, SIGNAL('clicked()'), app, SLOT('quit()'))
Qt::Object::connect() - мабуть, найважливіша особливість Qt. Виклик connect() встановлює односторонній зв'язок між двома об'єктами. Кожен об'єкт може мати як сигнали(для відправки повідомлень), так і слоти(для прийому повідомлень).
Тут сигнал clicked() кнопки quit зв'язаний із слотом quit() додатку app, так що при натисканні кнопки додаток завершує роботу.

quit.show
Віджет ніколи не відображається на екрані при створенні. Ви повинні викликати Qt::Widget::show(), щоб зробити його видимим.

app.exec
Запуск основного циклу програми.

У наступному прикладі ми створимо батьківський і дочірній віджети.
# -*- encoding: utf-8 -*-

require 'Qt'

app = Qt::Application.new(ARGV)

window = Qt::Widget.new
window.resize(200, 120)

quit = Qt::PushButton.new("Quit", window) do
  font = Qt::Font.new('Times', 18, Qt::Font::Bold)
  set_geometry(10, 40, 180, 40)
end

Qt::Object.connect(quit, SIGNAL('clicked()'), app, SLOT('quit()'))

window.show
app.exec

Розберемо нашу програму рядок за рядком.

window = Qt::Widget.new
Qt::Widget є базовим класом для всіх об'єктів інтерфейсу користувача. Він отримує події мишки, клавіатури та інші події від віконної системи, а також малює зображення на екрані.

window.resize(200, 120)
Задаємо розміри батьківського вікна.

quit = Qt::PushButton.new("Quit", window) do
  # ...
end
Створюємо дочірній віджет. Тут ми скористалися особливістю QtRuby передавши блок у конструктор віджета. Qt::PushButton створюється з батьківський віджетом (window). Дочірній завжди відображається в області його батьківського віджета.

set_geometry(10, 40, 180, 40)
Qt::Widget::setGeometry() приймає чотири аргументи: перші два х та у координати лівого верхнього кута кнопки. Останні два аргументи ширина кнопки і висота.

window.show
Коли викликається Qt::Widget::show() для батьківського віджета, він викликатиме відображення для усіх своїх дочірніх віджетів.

На сьогодні це все. А у наступних статтях ми докладніше розберемося, як з'єднати декілька віджетів використовуючи слоти і сигнали, а також дізнаємося, як позиціювати віджети у вікні.

Немає коментарів: