Программирование на языке Ruby - Хэл Фултон
Шрифт:
Интервал:
Закладка:
pack Left
end
top.pack Top
bottom.pack Bottom
Tk.mainloop
Здесь мы создали два фрейма. Верхний служит только для отображения температуры. Она измеряется по шкале Фаренгейта и для улучшения дизайна выводится крупным шрифтом (а символ градуса отображается маленькой буквой «о», расположенной справа сверху). Нижний фрейм содержит кнопки «вверх» и «вниз».
Обратите внимание на не встречавшиеся еще атрибуты объекта TkLabel. Метод font задает гарнитуру и размер шрифта, которым выводится текст метки. Строковое значение платформенно-зависимо; то, что приведено в примере, предназначено для ОС Windows. В системах UNIX обычно указывается длинное и малопонятное имя шрифта, принятое в X Window, например: -Adobe-Helvetica- Bold-R-Normal*-120-*-*-*-*-*-*.
Метод foreground задает цвет текста. Здесь мы передаем строку "green" (которая в Tk имеет предопределенный смысл). Если вы хотите знать, предопределен ли тот иной цвет в Tk, то самое простое — попробовать.
Аналогично метод background задает цвет фона, на котором выводится текст. В данном случае мы передаем строку в другом формате, а именно указываем красную, зеленую и синюю компоненты в шестнадцатеричном виде, как принято в языке HTML и других случаях. (Строка "#606060" соответствует приятному серому цвету.)
Мы не включили никакой кнопки «выхода» (чтобы не загромождать окно). Как обычно, для того чтобы закрыть приложение, достаточно щелкнуть по иконке Close в правом верхнем углу рамки окна.
Отметим использование метода configure в описании команд для кнопок; он изменяет текст метки по мере того, как текущая температура уменьшается или увеличивается. Мы уже говорили, что таким образом почти все атрибуты можно изменять во время выполнения, причем изменение отображается на экране незамедлительно.
Упомянем еще две операции над текстовыми кнопками. Метод justify принимает один параметр ("left", "right" или "center"), определяющий выравнивание текста внутри кнопки (по умолчанию подразумевается "center"). Мы говорили, что можно отображать многострочный текст; метод wraplength задает номер колонки, в которой происходит перенос слова.
Стиль кнопки можно изменить методом relief, придав ей трехмерный вид. В качестве параметра этому методу можно передать одну из строк: "flat", "groove", "raised", "ridge" (по умолчанию), "sunken" или "solid". Методы width и height явно задают размеры кнопки. Имеется также метод borderwidth и аналогичные. О других атрибутах (которых немало) вы можете прочесть в руководстве.
Рассмотрим еще один пример использования кнопки. На этой кнопке будет изображение, а не просто текст.
Я создал GIF-файлы с изображениями стрелок, указывающих вверх и вниз (up.gif и down.gif). Для получения ссылок на них можно воспользоваться классом TkPhotoimage, а затем передать эти ссылки в качестве параметров при создании кнопок.
up_img = TkPhotoimage.new("file"=>"up.gif")
down_img = TkPhotoimage.new("file"=>"down.gif")
TkButton.new(bottom) do
image up_img
command proc { tlab.configure("text"=>(temp+=1).to_s) }
pack Left
end
TkButton.new(bottom) do
image down_img
command proc { tlab.configure("text"=>(temp-=1).to_s) }
pack Left
end
Здесь просто заменены некоторые строки в первом примере. Если не считать внешнего вида кнопок, то поведение не изменилось. На рис. 12.2 показано окно приложения.
Рис. 12.2. Имитация термостата (с графическими кнопками)
12.1.4. Текстовые поля
Чтобы отобразить поле для ввода текста и манипулировать им, применяется виджет TkEntry. Как и следовало ожидать, для указания размера, цвета и поведения предусмотрены многочисленные атрибуты. Мы приведем довольно объемный пример, иллюстрирующий применение некоторых из них.
Поле ввода полезно лишь, если существует способ получить введенное в него значение. Обычно поле связывается с переменной (если быть точным, с объектом TkVariable), хотя можно воспользоваться и методом get.
Предположим, что мы разрабатываем telnet-клиент, который принимает четыре параметра: адрес хоста, номер порта (по умолчанию 23), имя пользователя и его пароль. Для красоты добавим еще две кнопки для операций «войти» и «отменить».
В представленном фрагменте используются фреймы, чтобы форма выглядела аккуратнее. Правда, написанный код не переносим, и настоящий знаток Tk с презрением отверг бы его. Но просто для сведения мы все-таки документировали этот «небрежный» подход к организации информации на экране.
Вид окна показан на рис. 12.3, а код — в листинге 12.2.
Рис. 12.3. Имитация telnet-клиента
Листинг 12.2. Имитация telnet-клиентаrequire "tk"
def packing(padx, pady, side=:left, anchor=:n)
{ "padx" => padx, "pady" => pady,
"side" => side.to_s, "anchor" => anchor.to_s }
end
root = TkRoot.new() { title "Telnet session" }
top = TkFrame.new(root)
fr1 = TkFrame.new(top)
fr1a = TkFrame.new(fr1)
fr1b = TkFrame.new(fr1)
fr2 = TkFrame.new(top)
fr3 = TkFrame.new(top)
fr4 = TkFrame.new(top)
LabelPack = packing(5, 5, :top, :w)
EntryPack = packing(5, 2, :top)
ButtonPack = packing(15, 5, :left, :center)
FramePack = packing(2, 2, :top)
FramelPack = packing(2, 2, :left)
var_host = TkVariable.new
var_port = TkVariable.new
var_user = TkVariable.new
var_pass = TkVariable.new
lab_host = TkLabel.new(fr1a) do
text "Host name"
pack LabelPack
end
ent_host = TkEntry.new(fr1a) do
textvariable var_host
font "{Arial} 10"
pack EntryPack
end
lab_port = TkLabel.new(fr1b) do
text "Port"
pack LabelPack
end
ent_port = TkEntry.new(fr1b) do
width 4
textvariable var_port
font "{Arial} 10"
pack EntryPack
end
lab_user = TkLabel.new(fr2) do
text "User name"
pack LabelPack
end
ent_user = TkEntry.new(fr2) do
width 21
font "{Arial} 12"
textvariable var_user
pack EntryPack
end
lab_pass = TkLabel.new(fr3) do
text "Password"
pack LabelPack
end
ent_pass = TkEntry.new(fr3) do
width 21
show "*"
textvariable var_pass
font "{Arial} 12"
pack EntryPack
end
btn_signon = TkButton.new(fr4) do
text "Sign on"
command proc {} # Ничего не делает!
pack ButtonPack
end
btn_cancel = TkButton.new(fr4) do
text "Cancel"
command proc { exit } # Просто выход.
pack ButtonPack
end
top.pack FramePack
fr1.pack FramePack
fr2.pack FramePack
fr3.pack FramePack
fr4.pack FramePack
fr1a.pack Frame1Pack
fr1b.pack Frame1Pack
var_host.value = "addison-wesley.com"
var_user.value = "debra"
var_port.value =23
ent_pass.focus
foo = ent_user.font
Tk.mainloop
Прежде всего разберемся с размещением виджетов. Сначала мы создали несколько фреймов, расположенных друг под другом. В самом верхнем фрейме есть два фрейма поменьше, расположенных по горизонтали.
В листинге 12.2 встречается также метод packing, единственная цель которого — сделать код чуточку чище. Он возвращает хэш, содержащий значения атрибутов padx, pady, side и anchor.
Объекты TkVariable предназначены для ассоциирования полей ввода с переменными. В классе TkVariable определен метод доступа value, который позволяет получать и устанавливать значение, хранящееся в объекте.
При создании объекта TkEntry, например ent_host, задаем атрибут textvariable, который связывает его с соответствующим объектом TkVariable. Иногда мы явно указываем ширину поля методом width; если это не сделано, то будет автоматически выбрана разумная ширина, обычно определяемая значением, которое в данный момент хранится в поле. Часто ширину подбирают методом проб и ошибок.
Шрифты задаются для полей ввода так же, как для меток. Аналогично обстоит дело и с цветами, которые в этом примере не задаются. Если шрифт пропорциональный, то два поля одинаковой ширины на экране могут оказаться различными.
Как обычно, необходимо вызвать метод pack. Мы немного упростили вызовы за счет использования констант.
Для поля, содержащего пароль, вызывается метод show, поскольку вводимое в него значение не должен видеть человек, заглядывающий через плечо. Вместо набираемых пользователем символов в таком поле будет отображаться символ, переданный методу show в качестве параметра (в данном случае звездочка).