флажок и переключатели. 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 миллисекунд. Следовательно,