Программирование в TCL/TK.

В данном разделе приведен пример программирования элемента GUI с использованием управляющих элементов типа «listbox» и ассоциированного с ним «scrollbar», с помощью которых возможен выбор одного или более элементов из списка, c прокруткой (горизонтальной) множества строк, загруженных в окно управяляющего элемента «listbox».

В разделе будут введены и рассмотрены следующие определения и понятия:

Make widget command
Widget command
Standard options supported by widgets
Widget specific options


Использован материал Manual Pages zu Tcl/Tk

Make widget command listbox.

ВНИМАТЕЛЬНО ИЗУЧИТЕ СТРУКТУРУ ДАННОЙ СТРАНИЦЫ!!
По ходу изложения мы будем возвращаться к этой странице, на которой перечислены Widget command, Standard options supported by widgets и Widget specific options для widget listbox!!

listbox – Create and manipulate listbox widgets.

SYNOPSIS

listbox pathName ?options?

Команда listbox создает новое окно и делает его widget listbox.
Дополнительные опции команды могут быть заданы в командной строке или запрошены в базе данных конфигурационных ресурсов, таких как colors, font, text и relief. Возвращаемый параметр – pathName.

Здесь вводим понятие Standard options supported by widgets.

В TK существует понятие – стандартные опции, поддерживаемые widget. Так обозначаются в TK общие конфигурационные опции. Не каждый widget поддерживает весь список этих опций, однако, если widget поддерживает какую-либо из перечисленных в этом списке опций (см. описание каждого конкретного widget), то widget может быть подвержен реконфигурированию по этой опции в соответствии с правилами, описанными ниже:

В приведенных в Standard options supported by widgets описаниях, "Command-Line Name" для каждой опции является переключателем для семейства команд и реконфигурирует команды wiget'а для передачи им этого значения. Например, если нами рассматривается командный переключатель -foreground:

Command-Line Name: -foreground or -fg
Database Name: foreground
Database Class: Foreground
Specifies the normal foreground color to use when displaying the widget.


и существует некий widget .a.b.c, то команда

.a.b.c configure -foreground black

может быть использована для задания или изменения фонового цвета на чёрный для wiget'а .a.b.c. Командные переключатели могут использоваться и в форме разрешённых сокращений. "Database Name" указывает на имя из базы данных дополнений (например, в файле .Xdefaults). "Database Class" указывает на значение, присваиваемое элементу базы данных дополнений.

Итак, listbox – это widget, который отображает список строк – одну строку в одной линии. В момент создания listbox пуст. Элементы listbox добавляются или удаляются из него с помощью специальных widget command для listbox :

insert

delete

Рассмотрим простейший пример заполнения listbox.


Пример № 1.

# Создание listbox для отображения в его окне списка цветов, составляющих радугу.

listbox .listbox1
pack .listbox1


#Далее показан пример использования widget command – insert для заполнения
#объявленного widget listbox элементами отображаемого списка цветов, начиная с
#нулевой строки

.listbox1 insert 0 red orange yellow green blue indigo violet

Здесь рассмотрим такую важную стандартную опцию, как -exportselection

Эта опция связывает возможный выбор (selection) в widget listbox с X-протоколом (протоколом стандарта Х11). Иными словами, опция –exportselection специфицирует, является ли выбор в listbox – Х-выбором.

Возможные значения этой опции - true, false, 0, 1, yes, или no. По умолчанию опция принимает значение 1 (true, yes), что означает:

Если выбор в widget listbox экспортируется, то этот выбор деселектирует текущий Х-выбор, выбор за пределами widget (outside widget) деселектирует любой выбор внутри widget (inside widget), а сам widget отвечает за возврат запрошенного выбора (selection), если в нем – в widget listbox – был осуществлен выбор. Иными словами, если выбор в listbox экспортируется, то соблюдается протокол стандарта Х11 для обработки событий.

listbox-selection доступен как переменная типа STRING.
Значение listbox-selection - это текст выбранного элемента + элемент окончания строки.

Усложним Пример №1. Добавим к этому примеру Tcl–процедуру, которая позволит нам визуально контролировать выбранный цвет из .listbox1 и его название. Для этого воспользуемся командой Tk bind, которая позволяет связывать Tcl-скрипты с Х-событиями (X-events).
Переопределим .listbox1, добавив стандартную опцию -exportselection.


Пример № 1-1.

#Создаем listbox для просмотра цветов радуги

listbox .listbox11 –exportselection 1
pack .listbox11
.listbox11 insert 0 red orange yellow green blue indigo violet


#Пока в данном listbox нет заранее объявленных связей для извлечения строки и
#распознавания ее содержания. Теперь свяжем событие «отжать клавишу» с левой
#клавишей мыши. Это никак не противоречит и не препятствует процессу выбора
#из listbox.

bind .listbox11 <ButtonRelease-1> {showindices}

#Определяем процедуру для просмотра выбранного цвета

proc showindices {} { puts [.listbox11 curselection] }

Здесь появляется еще одна widget command для listbox - curselection. Команда возвращает список, содержащий номера выбранных строк из списка listbox, в соответствии с объявленными режимами выбора. См. DEFAULT BINDINGS и специфическую для widget listbox опцию -selectmode. Как видно из опиcания, эта опция позволяет по разному определять поведение listbox с точки зрения выбора его строк – выбор может осуществляться по одной строке, по несколько строк, идущих подряд, и по несколько строк, расположенных в listbox не подряд. Возможные значения этой опции - single, browse, multiple, или extended. В приложениях, напиcанных с иcпользованием Tcl/Tk чаще всего используется значение по умолчанию browse.

Прокрутка содержимого окон widget’ов.

Существуют такие widget, у которых содержимое (список строк, строка символов или картинка) не полностью отображается в его видимом окне. Кроме listbox в список таких widget входят:

label
entry
text
canvas

Эти widget могут быть управляемы таким образом, что относящиеся к ним text, list или image могут быть «перемещены» или «прокручены» по горизонтали или вертикали в окне управляющего элемента – widget. Этот процесс называется scrolling’ом, и он может быть реализован путем посылки widget специальной widget command.

Возвращаемся к widget listbox.

Его специальные команды (widget command) для прокрутки:

xview

yview

Аргументы этих widget command очевидны. Важно отметить, что эта команда возвращает список, состоящий из двух элементов, лежащих в интервале 0 и 1. Первый элемент списка указывает на позицию listbox, находящегося наверху (слева) окна listbox, относительно всего списка (строки символов, если речь идет о горизонтальной прокрутке). Второй элемент списка указывает на позицию в listbox, лежащую сразу за последним видимым в окне элементом, относительно всего списка. Например (для widget command yview) если первый элемент списка равен 0.2, а второй – 0.6, это означает, что 20% списка (сверху) находится выше верхней границы окна widget listbox, средние 40% списка в данный момент видны в окне widget listbox и последние 40% списка находятся ниже границы видимого окна widget listbox.
Ниже будет показано, как эти же самые значения используются для прокрутки содержимого widget (в частности, widget listbox) с применением стандартных опций, предназначенных для этого: -yscrollcommand (-xscrollcommand).

Рассмотрим следующий пример, иллюстрирующий применение этих widget command.


Пример № 2.

#Уже созданный widget .listbox1, содержащий список цветов радуги, может быть
#управляем за счет посылки ему widget command yview.

.listbox1 yview 3
.listbox1 yview 10
.listbox1 yview 20
.listbox1 yview 1
.listbox1 yview end


Если вы реализуете этот скрипт, то сможете убедиться, что содержимое .listbox1 будет двигаться вверх и вниз.

Рассмотрим еще один пример, в котором listbox, содержащий список европейских городов, управляется двумя кнопками, с помощью которых содержимое listbox прокручивается вертикально.


Пример № 3.

# Создаем listbox, содержащий список европейских городов.

listbox .listbox2

# Далее следует заполнение listbox с помощью widget command insert.
# Заполнение происходит начиная с нулевой строки.

.listbox2 insert 0 Aberdeen Alicante Athens Basel Berne Bilbao Cannes Edinburg Glasgow Geneva Lisboa London Madrid Munich Paris Rome Rouen Venice Zurich

# Для прокрутки содержимого listbox организуем две кнопки «UP» и «DOWN»

# Для кнопок организуем отдельный frame

frame .fr –relief raised
button .fr.button1 –text "UP" –command {.listbox2 yview 1}
button .fr.button2 –text "DOWN" –command {.listbox2 yview 10}


# Теперь упакуем все объявленные widget

pack .listbox2 .fr –side left –padx 1m –fill x
pack .fr.button1 .fr.button2 –padx 1m –pady 2m –fill x –fill y


Ассоциирование прокручиваемых управляющих элементов со scrollbar widget (на примере widget listbox).

Все widget, допускающие горизонтальную и вертикальную прокрутку своего содержимого, используют в качестве стандартных опции –xscrollcommand и –yscrollcommand. Именно эти опции позволяют прокручивать содержимое widget в обоих направлениях. Эти две опции (часто используются в сокращенной виде: –xscroll и –yscroll) специфицируют префикс для команды, используемой для связи с горизонтальным и вертикальным widget scrollbar. При любом изменении, которое происходит в окне widget, т.е. изменении с контентом widget, или любом другом изменении, приводящем к изменению экрана или перемещения ползунка scrollbar, widget будет выполнять Tcl-команду путем объединения scroll-команды и двух чисел. Каждое из этих чисел – это положительная десятичная дробь в диапазоне от 0 до 1; служит для индикации позиции в документе. 0 – означает начало документа, 1 – конец документа. 0.33 отмечает позицию на границе первой трети документа и т.д. Первая дробь указывает на позицию первой строки в видимом окне widget, а вторая – на позицию, сразцу после последней видимой строки в окне. Команда затем передается интерпретатору Tcl на выполнение.
Как правило, опция -yscroll (-xscroll) имеет значение ".tt set", где .tt - это имя (path name) widget scrollbar, с которым ассоциируется прокручиваемый widget.
В результате исполнения команды widget command set widget, ассоциированный со scrollbar’ом, получает информацию о его состоянии и изменяет свое состояние – в видимом окне за счет исполнения опции -yscroll (-xscroll).

В этой связи рассмотрим Пример № 4, реализующий прокрутку widget listbox с использованием ассоциированного с ним scrollbar’а.


Пример № 4

listbox .lb1 -exportselection 1 -selectmode single -yscroll ".sb1 set"
pack .lb1
.lb1 insert 0 red orange yellow green blue indigo violet weiss black blue red red red red
bind .lb1 <ButtonRelease-1> {show}

#
scrollbar .sb1 -relief sunken -command ".lb1 yview"
#
pack .sb1 .lb1 -side right -fill y -expand yes
proc show {} {
puts [.lb1 curselection]
}


С подробным описанием команд Tcl, использованных в процедурах последних примеров, можно ознакомиться здесь. Кроме того, все команды Tcl, использованные в примерах данного раздела, описаны ниже.

В Примере №4 впервые появился widget srollbar.
Рассмотрим структуру make widget command scrollbar подробнее.

scrollbar - Create and manipulate scrollbar widgets

SYNOPSIS


scrollbar pathName ?options?

Команда создает и позволяет манипулировать widget scrollbar.

Для нас наибольший интерес представляет специфическая для данного widget опция -command. Именно эта опция позволяет ассоциировать прокручиваемые управляющие элементы с widget scrollbar.

Эта опция специфицирует префикс для вызова Tcl-команды, которая изменяет вид (view) в widget'е, ассоциируемом с widget scrollbar. Когда пользователь манипулирует с ползунком scrollbar, запрашивая, таким образом, изменение вида в окне основного widget (listbox, entry, label, text или canvas), вызывается Tcl-команда. Активная команда состоит из этой опции и может быть дополнена, как описано ниже. Опция –command почти всегда имеет значение:

".t xview" или
".t yview",


где .t – имя прокручиваемого widget, ассоциируемого со scrollbar’ом. С другой стороны, все прокручиваемые widget (listbox, entry, label, text или canvas) имеют widget command xview и yview, которые собственно и управляют процессом скроллирования в таких widget. Таким образом осуществляется ассоциирование скроллируемых widget с widget scrollbar.

Рассмотрим последний, комплексный пример работы с widget listbox.


Пример № 5

#!/usr/local/bin/wish -f
# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #
# Tсl/Tk - script для binding, listing, scrolloing, filling и select #
# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #
# Объявляем listbox .lb1, ассоциируем его со scrollbar’ом .sb1 благодаря
# использованию стандартной опции -yscrollcommand
#
listbox .lbl -exportselection 1 -selectmode single –yscroll ".sbl set"
#
# Объявляем scrollbar .sb1, ассоциируем его с объявленным ранее listbox .lb1 в
# спцифической для данного widget опции –command
#
scrollbar .sb1 -relief sunken -command ".lb1 yview"
#
# Упаковываем объявленные widget’ы.
#
pack .sb1 .lb1 -side right -fill y -expand yes
#
# Связываем с помощью команды bind Х-событие «отжатие левой клавиши мыши» с
# Tcl-процедурой show, которая позволяет нам контролировать сделанный из listbox
# выбор цвета – собственно цветом и по названию.
#
bind .lbl <ButtonRelease-1> {show}
#
# Объявляем метку .l1 для отображения выбранного цвета и его названия.
#
label .l1 -relief sunken -text "String von Listbox"
#
# Упаковываем метку, объявляем и упаковываем кнопку «ВЫХОД»
#
pack .l1
button .b1 -text "EXIT" -command {exit}
pack .bl

#
# Подготовка widget listbox .lb1
#
# Заполнение widget listbox .lb1 значениями из отсортированного файла rgb.txt
#
exec cut -f 3- rgb.txt > rgb1.txt
#
# Использованные команды Tcl в цикле заполнения listbox .lb1, представленном ниже,
# будут описаны в конце листинга данного скрипта.
#
set rgb [open rgb1.txt r]
while {[eof $rgb] == 0} {
set colorstr [gets $rgb]
if {$colorstr != ""} {
.lb1 insert 0 $colorstr
}
}
.lb1 delete 0
close $rgb

#
#
# Процедура отображения выбранного в listbox .lb1 цвета и его названия
# на метке label .l1
#
proc show {} {
global w
global text
set w [.lb1 curselection]
set text [.lb1 get $w]
.l1 configure -text $text -bg $text
}

#Конец листинга программы


Ниже приведено короткое описание Tcl-команд, использованных в примерах данного раздела.


open

Открывает канал для связи с файлом или программой.

Синтаксис

open fileName
open fileName access
open fileName access permissions


Описание

Эта команда открывает файл, последовательный порт или командный конвейер и возвращает идентификатор канала, который может использоваться в дальнейшем в таких командах, как read, puts и close. Если первый символ атрибута fileName не равен «|»; то команда открывает файл fileName, соответственно значение аргумента fileName должно соответствовать обычным соглашениям.
Аргумент access, если он используется, указывает разрешенные режимы доступа к файлу. Аргумент access может указываться в одной из двух нотаций. В первой он может иметь следующие, значения:

r
Открывает файл только на чтение. Это значение по умолчанию.

r+
Открывает файл на чтение и запись. Файл должен существовать.

w
Открывает файл только на запись. Удаляет содержимое файла, если он существовал. Если нет, то создает новый файл.

w+
Открывает файл на чтение и запись. Удаляет содержимое файла, если он существовал. Если нет, то создает новый файл.

a
Открывает файл на чтение. Файл должен существовать. Новые данные записываются в конец файла.

а+
Открывает файл на чтение и запись. Если файл не существует, создает новый файл. Новые данные записываются в конец файла.

Во второй нотации аргумент access может содержать набор из флагов, описанных ниже. Среди флагов обязательно должен быть один из следующих: RDONLY, WRONLY или RDWR.

RDONLY
Открывает файл только на чтение.

WRONLY
Открывает файл только на запись

RDWR
Открывает файл на чтение и запись.

APPEND
Переставляет указатель в конец файла перед каждой записью.

CREAT
Создает файл, если он не существует. Без этого флага попытка открыть несуществующий флаг приведет к ошибке.

EXCL
Если указан также флаг CREAT, то будет сгенерирована ошибка, если файл уже существует.

NOCTTY
Если файл открыт для терминального устройства, этот флаг не позволяет ему стать управляющим терминалом процесса.

NONBLOCK
Позволяет в неблокирующем режиме открыть файл и, возможно, выполнять в этом режиме последующие операции ввода-вывод а. Последствия использования этого флага зависят от платформы и устройства. Предпочтительнее вместо него использова ть команду fconfigure.

TRUNC
Если файл существует, то его содержимое удаляется. Если файл создается при выполнении команды open, то аргумент permissions (целое число) используется для установки п рав доступа к вновь созданному файлу. Значение по умолчанию 0666.

set

Команда читает и записывает значения переменных.

Синтаксис

set varName?value?

Описание

Команда set возвращает значение переменной varName. Если задан параметр value, то команда присваивает переменной varName значение value и возвращает значение value. Если такой переменной не существовало, тогда она создается вновь. Если varName содержит открывающую скобку и заканчивается закрывающей скобкой, тогда это элемент массива. Символы до открывающей скобки являются именем массива, символы между скобками есть индекс этого элемента в массиве. В противном случае команда адресуется к скалярной переменной. Обычно имя переменной указывается без указания пространства имен, в котором она содержится. При этом соответствующая переменная для чтения или записи ищется в текущем пространстве имен. Если же в имени переменной присутствуют имя пространства имен, то она ищется в указанном пространстве имен. Если команда используется вне тела процедуры, то varName есть имя глобальной переменной (если текущее пространство имен есть глобальное пространство) или переменной текущего пространства имен. В теле процедуры varName есть имя параметра или локальной переменной процедуры, если она не объявлена глобальной переменной или переменной пространства имен с помощью команды global или variable соответственно.


eof

Команда проверяет в канале условие конца файла.

Синтаксис

eof channelId

Описание

Команда eof возвращает 1, если во время последней операции ввода в канале channelId произошло условие конца файла, и 0 — в противном случае.


gets

Команда читает строку из канала.

Синтаксис

gets channelId?varName?

Описание

Команда gets читает из канала channelld очередную строку символов. Если имя переменной varName не задано, тогда команда возвращает полученную строку за исключением символов конца строки. Если varName задано, тогда команда записывает полученную строку в переменную и возвращает количество символов в принятой строке.
Если при поиске конца строки был обнаружен конец файла, команда возвращает всю полученную информацию вплоть до конца файла.
Если канал находится в неблокирующем режиме и поступила неполная входная строка, то команда не использует поступившие данные и возвращает пустую строку.
Если указана переменная varName и возвращается пустая строка из-за конца файла или из-за неполноты полученной строки, команда возвращает —1.
Обратите внимание, что если аргумент varName не задан, конец файла и неполная строка приведут к тому же результату, что и строка, состоящая из символа конца строки. Команды eof и fblocked позволяют различить эти ситуации.

close

Команда закрывает открытый канал.

Синтаксис

close channelId


Описание

Команда close закрывает канал, идентификатор которого задан аргументом channelId. Идентификатор channelId возвращается командами open и socket при открытии канала. Команда отправляет все накопившиеся в выходном буфере данные на выходное устройство канала, удаляет все данные во входном буфере, закрывает назначенное каналу устройство или файл. Доступ к каналу прекращается. Для каналов в блокирующем и неблокирующем режимах действие команды несколько различно. Если канал находится в блокирующем режиме, команда завершается только после завершения вывода данных из буфера. В противном случае команда завершается немедленно, а вывод данных из буфера производится в фоновом режиме. Канал закрывается после завершения вывода. Если канал в блокирующем режиме открыт для конвейера, команда close завершается после завершения порожденного процесса. Если канал совместно используется несколькими интерпретаторами, то команда делает канал channelId недоступным в вызвавшем команду интерпретаторе, но не оказывает никакого другого действия на канал, пока все использующие канал интерпретаторы не закроют его. При выполнении команды в последнем из интерпретаторов, использовавших его, выполняются описанные выше действия. Команда close возвращает пустую строку. Она может порождать ошибку, если при выводе данных произошла ошибка.

Подстановка команд со скобками

При появлении в поле команды открывающей квадратной скобки выполняется подстановка команды. Все символы внутри скобок считаются командой, и она исполняется немедленно. Затем результат этого исполнения подставляется вместо текста в скобках. Например, рассмотрим команду

set a [set b]

Когда у команды set задан только один аргумент, тогда это есть имя переменной, и set возвращает значение этой переменной. В этом случае, если переменная b имеет значение foo, то предыдущая команда эквивалентна команде

set a foo

Квадратные скобки можно использовать более сложными способами. Например, если переменная b имеет значение foo, a переменная с имеет значение gorp, то команда

set a xyz[set b].[set с]

эквивалентна команде

set a xyzfoo.gorp

Команда в квадратных скобках может содержать несколько команд, разделенных обычным образом — строками или точками с запятой. В этом случае для подстановки используется значение последней команды. Например, последовательность команд

set a x[set b 22 ехрr $b+2]x

Эквивалентна команде

set a x24x

Если поле заключено в фигурные скобки, то квадратные скобки и символы между ними не интерпретируются специальным образом, а передаются в аргумент без изменения.

Подстановка переменных с $

Символ $ можно использовать в качестве краткой фрмы для подстановки переменных. Если у аргумента, не заключенного в фигурные скобки, имеется символ $, то выполняется подстановка переменной. Символы после $ вплоть до первого символа, не являющегося цифрой, буквой или подчеркиванием, считаются именем переменной, и строковое значение этой переменной подставляется вместо ее имени. Например, если переменная foo имеет значение test, то команда:

set a $foo. с

эквивалентна команде

set a test.с

Существует две специальные формы для подстановки переменных. Если следующим после имени переменной является открывающая скобка, то переменная считается именем массива, и все символы между открывающей скобкой и следующей закрывающей скобкой считаются индексом внутри этого массива. Команды и переменные, используемые в качестве индекса, обрабатывается перед операцией извлечения элемента массива. Например, если переменная х есть массив и один его элемент по имени first имеет значение 87, а второй по имени 14 — значение more, то команда:

set a xyz$x(first)zyx

эквивалентна команде

set a xyz87zyx

Если переменная index имеет значение 14, то команда:

set a xyz$x($index)zyx

эквивалентна команде

set a xyzmorezyx




Hosted by uCoz