Tcl + Tile = молниеносное создание кроссплатформных GUI с нативными виджетами

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

По работе мне близко последнее. Чтобы не править и не перекомпилировать программу управления устройством каждый раз, когда добавляется новый параметр, мы написали универсальный конфигуратор, который по XML-файлу с описанием параметров устройства строит виджеты работы с ними. Специфичные для конкретного устройства функции вынесены в библиотеки. В последнее время этого стало мало -- нужно уметь задавать зависимости между значениями, введёнными пользователем в одни виджеты, и внешним видом других. Можно конечно продолжать наворачивать XML-схему и код её интерпретации. Другой вариант -- использовать интерпретируемый язык для создания пользовательского интерфейса.

Первое, что приходит в голову: использовать возможности браузеров. Однако ограничения безопасности не позволят через JavaScript работать напрямую с файлами, сокетами, портами. Непонятно как рисовать графики. Для всего этого придется делать какие-то плагины к браузеру. Математику, физику или радиолюбителю точно не захочется с этим связываться. Можно использовать Python + PyGTK, но есть более изящный, легковесный и простой в освоении инструмент специально для упомянутых задач. Это Tcl (Tool control language).

Вместе с расширением Tk для создания GUI, этот кроссплатформный интерпретируемый язык позволяет создавать GUI со скоростью мысли.

Вот такой код создаёт форму с кнопкой, выводящей результат вычисления 2+2 по клику:

button .btn -text "Ok" -command {set res [expr 2+2]; puts "Результат = $res";}
pack .btn

Выглядит это так:

Причём внешний вид сохранится на всех поддерживаемых Tcl платформах, включая Windows, Linux и Mac OS. Т.е. сопровождая свой интеллектуальный продукт программой на Tcl вы не привязываете его потребителя к определённой платформе.

Можно ли сделать чтобы Tcl/Tk код под каждой платформой рисовал нативные (родные) виджеты? О, да! В последнее время бурно развивается расширение Tile, позволяющее реализовать и подключать темы, использующие родные для платформы контролы. В поставку Tile входят темы, использующие родные контролы Windows и Mac OS. Tile уже в ходит в бету Tcl 8.5. Можно скачать и скомпилировать для 8.4. Устанавливаем tcl8.4-dev, tk8.4-dev и все зависимые пакейджы. Качаем tile-0.7.8.tar.gz (600Кб). Делаем:

./configure --with-tcl=/usr/lib/tcl8.4 --with-tk=/usr/lib/tk8.4
make
make install

Меняем в коде скрипта button на ttk::button, либо вставляем строку namespace import ttk::* чтоб перекрыть команды Tk командами Tile. Результат под Linux:

Под Windows и Mac OS кнопка уже была бы неотличима от родных кнопок и использовала бы системные настройки отображения. Под GTK законченной темы пока нет, только недоделанный проект один нашел. Зато есть тема под QT, Называется tileqt, поддерживает qt3 и 4.

Устанавливаем libqt3-mt-dev. Качаем tileqt.

./configure --with-tcl=/usr/lib/tcl8.4 --with-tk=/usr/lib/tk8.4
make
make install

У меня на Debian 3.1 чтоб всё скомпилировалось пришлось в файле tileqt0.4b1/generic/tileQt_QtHeaders.h закомментировать #include <qobjcoll.h> и #include <qwidcoll.h>, а в /usr/share/qt3/include/qt.h закомментировать #include <qvfbhdr.h>. Вставляем в скрипт tile::setTheme tileqt. Результат:

Скомпилированная библиотека tileqt занимает 6Мб! Автор tileqt, Georgios Petasis (??????), по поводу размера ответил в письме что у него тоже такой же большой размер библиотеки, что-то не так в линковке и он пока не разобрался... Есть идеи? Может кто поможет греческому коллеге?

Синтаксис команд Tile частично совместим с Tk. Команды вроде те же, но вместо опций (например для задания цвета фона) используются стили. Для новых программ на Tcl это не проблема, просто пользуем стили и забываем про опции Tk. А для портирования старых больших Tk-программ на Tile нужно написать обёртку, реализующую неподдерживаемые Tile опции Tk через стили Tile. Что-то подобное сделал автор программы aMSN в плагине Chameleon к ней.

Сходу адаптировать плагин к попавшейся под руку программе TkDVD у меня не получилось, но это можно сделать, если разобраться в механизмах неймспейсов и перекрытии опций, в чем должны помочь исходники Chameleon. Буквально через час, после того как я оставил попытки прикрутить Chameleon к TkDVD и отправил kakaroto просьбу о помощи, в CVS появился коммит с таким комментарием: Finally made the necessary changes to make it 'universal'.. added the pkgIndex.tcl file and now anyone can just do a 'package require Chameleon' to add Chameleon capabilities to his application, and do a ::chameleon::ConfigureChameleon to configure it. Всё равно TkDVD не поддался. Напишите если у кого получится.

Тем, кто на короткой ноге с QT, стоит взглянуть на qtcl. Я вообще не смог его скомпилировать, но вещь мощная: расширение понимает ui-файлы xml-gui-tree описания интерфейсов из gui-designer, позволяет работать из Tсl с любыми объектами QT, в том числе созданными не из скрипта, а из других программ! Окно с кнопкой делается так:

qt create QDialog .top
qt create QPushButton .top.btn text Ok
qt .top.btn set pixmap test.png
qt .top show

Всё, теперь по-быстрому переписываем пол KDE на Tcl и высылаем разработчикам KDE4 в виде патча, чтоб быстрее релиз делали :)

Tcl, Tk и большинство расширений распространяются под лицензией в стиле MIT. С исходниками и производными от них можно делать что угодно ни с чем при этом не соглашаясь.

Tcl/Tk входит в состав большинства дистрибутивов Linux. Под Windows можно скомпилировать.

Сомнения относительно надёжности Tcl для серьёзного коммерческого использования развеивает статья в январском Linux Format (спасибо Димону! :). "Tcl использовался в ПО телескопа 'Хаббл'... ПО модуля оператора буровой вышки компании Shell... принят на вооружение фирмами Oracle и IBM".

Блог: RU Linux

George, автор библиотеки tileqt, подсказал, что по умолчанию билдится дебаг-версия и удалить отладочную информацию из неё можно командой strip. Из 6Мб остаётся 92Кб :)

Делать GTK2 GUI на Tcl можно используя gnocl. Это никак не связанное с Tile и не совместимое с Tk расширение для работы с GTK2. Т.е. портировать существующую Tk-программу, как и в случае с qtcl, будет сложно. Среди преимуществ -- малый размер, хорошая документация, простота освоения.

Что-то я не понимаю как тему прикрутить к существующему приложению на Tcl/Tk. Вот есть у меня Tkabber, есть Tile. Куда вставлять tile::setTheme tileqt?

tile::setTheme tileqt надо до вывода интерфейса в любое место вставить, где-нибудь в начале, но этого мало т.к. надо все контролы переделать через tile:

"Меняем в коде скрипта button на ttk::button, либо вставляем строку namespace import ttk::* чтоб перекрыть команды Tk командами Tile."

Каптча просто аццкая. Нифига непонятно где lower, а где upper case. По 100 раз приходится вводить.

) сделал все в lower