logo
Программирование на языке Ruby

Листинг 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 в качестве параметра (в данном случае звездочка).

Я уже сказал, что кнопки тут нужны только для красоты. Кнопка Sign on вообще ничего не делает, a Cancel завершает программу.

У полей ввода есть и другие атрибуты. Можно изменять значение из программы, не заставляя пользователя вводить его; можно задать шрифт и цвета; можно изменить характеристики курсора, указывающего место вставки, и перемещать его в нужное место. И многое, многое другое. Полное описание вы найдете в руководстве.

Раз уж мы заговорили о вводе текста, будет уместно упомянуть виджет Text. По сравнению с полем ввода это примерно то же, что двухместный планер по сравнению космическим челноком. Виджет Text спроектирован специально для ввода больших фрагментов текста, насчитывающих много строк, и по существу является основой для создания полноценного редактора. Он довольно сложен, поэтому мы не будем его здесь рассматривать.