пользователю. В данном случае текст инициализируется в предыдущей строчке. Следующая строчка говорит метке, что она должна отобразить себя на экране.
На последнем шаге вызов арр.ехес запускает цикл обработки событий. Он не возвращает управления, пока приложение не завершится. Обычно это происходит, когда пользователь нажимает кнопку закрытия окна.
12.4.3. Кнопки
Создание кнопки в QtRuby сводится к созданию экземпляра класса Qt::PushButton
(см. листинг 12.14 и рис. 12.7). Обычно при нажатии кнопки нужно выполнить некоторое действие. Для этого применяется механизм событий и слотов QtRuby.
require 'Qt'
class MyWidget < Qt::Widget
slots 'buttonClickedSlot()'
def initialize(parent = nil)
super(parent)
setWindowTitle('QtRuby example');
@lineedit = Qt::LineEdit.new(self)
@button = Qt::PushButton.new('All Caps!',self)
connect(@button, SIGNAL('clicked()'),
self, SLOT('buttonClickedSlot()'))
box = Qt::HBoxLayout.new
box.addWidget(Qt::Label.new('Text:'))
box.addWidget(@lineedit)
box.addWidget(@button)
setLayout(box)
end
def buttonClickedSlot
@lineedit.setText(@lineedit.text.upcase)
end
end
app = Qt::Application.new(ARGV)
widget = MyWidget.new
widget.show
app.exec
Рис.12.7. Кнопки в Qt
В этом примере мы создали собственный класс виджета с именем MyWidget
, он наследует классу Qt::Widget
, являющемуся предком любого нестандартного виджета.
Перед инициализацией мы подготовили список слотов, которые будут определены в нашем классе. Слоты — это обычные методы класса, но необходимо указать их имена, чтобы во время выполнения QtRuby знала, что мы собираемся использовать их именно в качестве слотов. Метод класса slots
принимает список строк:
slots = 'slot1()', 'slot2()'
Инициализатор класса принимает аргумент parent
, он есть почти у всех виджетов в Qt и определяет, какой виджет будет владельцем вновь создаваемого. Значение nil
означает, что это «виджет верхнего уровня», у которого нет владельца. Концепция «владения», наверное, имеет более понятный смысл в C++; родители владеют своими детьми, то есть при уничтожении или удалении родителя удаляются и все его потомки.
Наш класс создает объект Qt::LineEdit
для ввода текста и кнопку Qt::PushButton
с надписью All Caps!
. В качестве родителя каждому виджету передается self. Это означает, что создаваемый экземпляр MyWidget
«усыновляет» эти виджеты.
Далее мы обращаемся к ключевой части библиотеки Qt — механизму соединения сигналов со слотами. В классе Qt::Pushbutton
определен сигнал clicked
, который испускается при нажатии кнопки. Этот сигнал можно соединить со слотом, в данном случае с методом buttonClickedSlot
. Имя слота может быть любым, суффикс Slot
мы употребили просто для наглядности.
В самом конце мы создаем экземпляр класса Qt::HBoxLayout
. При добавлении виджетов в этот контейнер он автоматически изменяет их размеры, так что нам больше не о чем беспокоиться.
12.4.4. Текстовые поля
Как видно из листинга 12.14, в QtRuby есть класс Qt::LineEdit
для ввода одной строки текста. Для ввода нескольких строк предназначен класс Qt::TextEdit
.
В листинге 12.15 демонстрируется многострочное текстовое поле. Под ним расположена метка, в которой отображается текущая длина текста (рис. 12.8).
require 'Qt'
class MyTextWindow < Qt::Widget
slots 'theTextChanged()'
def initialize(parent = nil)
super(parent)
@textedit = Qt::TextEdit.new(self)
@textedit.setWordWrapMode(Qt::TextOption::WordWrap)
@textedit.setFont( Qt::Font.new('Times', 24) )
@status = Qt::Label.new(self)
box = Qt::VBoxLayout.new
box.addWidget(@textedit)
box.addWidget(@status)
setLayout(box)