флажок и переключатели. Qt::ButtonGroup предназначен для логической группировки кнопок, флажков и переключателей. На их визуальное расположение он никак не влияет, зато обеспечивает, к примеру, взаимное исключение (гарантирует, что только один из группы виджетов может быть отмечен). В данном случае этот объект будет источником сигнала buttonClicked, который испускается при нажатии любой кнопки в группе.
Этот сигнал отличается от виденных ранее тем, что ему сопутствует аргумент, а именно объект, по которому щелкнули мышкой. Обратите внимание на то, как синтаксис — QAbstractButton* — напоминает о C++-ных корнях Qt. В некоторых случаях употребления принятой в C++ нотации для обозначения типов параметров не избежать (хотя в будущих версиях это, возможно, и исправят).
В результате такого вызова метода connect при щелчке по любому виджету, принадлежащему группе, этот виджет будет передан слоту somethingClicked. Наконец, мы создаем метку Qt::Label, контейнер Qt::QBoxLayout и увязываем все вместе.
Внутри слота somethingClicked мы модифицируем текст метки при щелчке по любому переключателю или флажку. В данном случае выводится имя класса объекта, который испустил сигнал, приведший к вызову слота.
Если встроенных виджетов недостаточно, то Qt предоставляет мощную систему рисования для создания собственных. В листинге 12.17 приведен небольшой пример, иллюстрирующий малую часть возможностей.
require 'Qt'
class TimerClock < Qt::Widget
def initialize(parent = nil)
super(parent)
@timer = Qt::Timer.new(self)
connect(@timer, SIGNAL('timeout()'), self, SLOT('update()'))
@timer.start(25)
setWindowTitle('Stop Watch')
resize(200, 200)
end
def paintEvent(e)
fastHand = Qt::Polygon.new([Qt::Point.new(7, 8),
Qt::Point.new(-7, 8),
Qt::Point.new(0, -80)])
secondHand = Qt::Polygon.new([Qt::Point.new(7, 8),
Qt::Point.new(-7, 8),
Qt::Point.new(0, -65)])
secondColor = Qt::Color.new(100, 0, 100)
fastColor = Qt::Color.new(0, 150, 150, 150)
side = [width, height].min
time = Qt::Time.currentTime
painter = Qt::Painter.new(self)
painter.renderHint = Qt::Painter::Antialiasing
painter.translate(width() / 2, height() / 2)
painter.scale(side / 200.0, side / 200.0)
painter.pen = Qt::NoPen
painter.brush = Qt::Brush.new(secondColor)
painter.save
painter.rotate(6.0 * time.second)
painter.drawConvexPolygon(secondHand)
painter.restore
painter.pen = secondColor
(0...12).each do |i|
painter.drawLine(88, 0, 96, 0)
painter.rotate(30.0)
end
painter.pen = Qt::NoPen
painter.brush = Qt::Brush.new(fastColor)
painter.save
painter.rotate(36.0 * (time.msec / 100.0))
painter.drawConvexPolygon(fastHand)
painter.restore
painter.pen = fastColor
(0...60).each do |j|
if (j % 5) != 0
painter.drawLine(92, 0, 96, 0)
end
painter.rotate(6.0)
end
painter.end
end
end
app = Qt::Application.new(ARGV)
wid = TimerClock.new
wid.show
app.exec
Созданный в этом примере виджет называется TimerClock. В инициализаторе мы создаем объект Qt::Timer, который конфигурируется для периодического испускания сигнала. Его сигнал timeout мы соединяем со слотом update нашего виджета. Это встроенный слот, он заставляет виджет перерисовать себя.
Таймер запускается методом start. Переданный ему аргумент говорит, что таймер должен срабатывать (и испускать сигнал timeout) каждые 25 миллисекунд. Следовательно,
