LINUX.ORG.RU

Tcl/tk. GUI на SVG-виджетах. Часть I

 , , , ,


1

1

Хочу представить свой пет-проект . Создан он в недрах tсl/tk, который, по моему мнению, многие недооценивают. В статье речь пойдет не столько о tcl (хотя все примеры и сам проект написаны именно на нем), а сколько о tk.

Удобство tk мало кто не признает. Но как только покажешь приложение, в котором gui разработано на tk, то тут же можешь услышать - опять этот убогий, примитивный, в лучшем случае устаревший интерфейс. И я здесь я соглашусь с этими критиками. Предпринималось немало попыток улучшение презентабельности tk-виджетов (помимо ttk-виджет). Но даже они на фоне пользовательского интерфейса на мобильниках, на qt или gtk смотрятся бледновато.

Мои ожидания, связанные с выходом tcl/tk-9.0, в плане внешнего вида виджетов не оправдались.

А поскольку я фанат tcl/tk, то мне очень хотелось бы поправить это положение. Понятно, что эту проблему можно решить путем привлечения SVG-графики. Поддержка SVG-графики в tcl/tk реализована через пакет tkpath. Сразу отмечу, что поддержка svg-графики сегодня есть и в пакете tko, которая в нем реализована по образу и подобию tkpath. Различия в интерфейсах для работы с svg-графикой в них минимальны.

Помимо пакета tkpath (tko) для реализации проекта понадобился еще и пакет treectrl, о его роли будет рассказано позже.

Так родился проект, в недрах которого были разработаны виджеты на базе векторной графики, а именно svg-виджеты. Эти svg-виджеты и представлены в скриншоте к статье.

Проект включает в себя три пакета, а именно svgwidgets, svg2can и tkfe_svg. Первый пакет предназначен для создания собственно svg-виджетов. Пакет svg2can предназначен для экспорта на холст изображений из svg-файлов, а пакет tkfe_svg обеспечивает приложения файловым проводником. Все эти пакеты добавлены в состав интерпретаторов tclexrcomp_svg для платформ Linux и Windows. Сам проект, который включает перечисленные выше пакеты, интерпретаторы и примеры можно найти на github-e. Здесь же в папке applications можно найти и приложение cryptoarmpkcs_svg_linux64 для работы с электронной подписью как образец использования svg-виджетов.

Поэтому можно скачать и запустить приложение cryptoarmpkcs_svg_linux64, чтобы посмотреть, как выглядит приложение на базе svg-виджетов.

Скачав проект, запустите интерпретатор tclexecomp_v200_svg_Lin64.

После запуска на экране появится графическая консоль интерпретатора tcl/tk.

Первое что можно сделать, это посмотреть с какой версией tcl/tk вы работаете:

% puts $tcl_patchLevel
8.6.14
%

А на втором шаге, следует посмотреть доступные пакеты:

% foreach {p1 p2 p3 } [glob -types {d} -directory /cvfs/modules *] {
    puts "[file tail $p1]\t\t\t[file tail $p2]\t\t\t[file tail $p3]"
}
tdbcpostgres1.1.7	tksvg0.6		tkfe_svg1.0
tclRFB0.5		tktray1.3.9		vfs1.4.2
sqlite3.44.2		zstd1.0		        scrollutil_utils
tbcload1.7.2		Tclxml3.2		Tktable2.10
itcl4.2.4		mentry4.2		extrafont1.3
udp1.0.11		tdbcmysql1.1.7	        Img1.4.14
scrolledwidget0.2	tcltls1.7.22		pgintcl3.5.1
cloudtk		        thread2.8.9		scrollutil2.2
Trf2.1.4		tkdnd2.9.4		tksvg0.12
TclReadLine1.4	        Imagescale0.1	        treectrl2.4.3
tko			wcb4.0		        trofs0.4.9
tdbcodbc1.1.7	        bwidget1.9.16		tcllib1.21
Tkhtml3.0		tclcompiler1.7.4	html3widget0.2.6.1
svgwidgets0.3.3	        spritz1.0		tdom0.9.3
imgtools0.3		tdbc1.1.7		pdf4tcl0.9.4
tklib0.7		tablelist7.2		SVG2CAN
tclx8.4			tkpath0.3.3		expect5.45.4
bgexec3.0						
%

И убедиться, что требуемые пакеты (tkpath, treectrl, svgwidgets, svg2can и tkfe_svg) в наличии. Если их не окажется, то надо будет ручками добавить путь к требуемым пакетам в переменную auto_path.

В репозитории TkSVGwidgets в папке examples лежат tcl-скрипты, демонстрирующие svg-виджеты. Все примеры готовились на платформе linux в кодировке utf-8.

Примеры можно запускать как из командной строки:

$tclexecomp_v200_svg_Lin64 ~/TkSVGwidgets/examples/скрипт_button_PACK.tcl

так и из меню интерпретатора tclexecomp_v200_svg_Lin64 (File->Интерпретировать файл -><выбранный файл>).

Результаты работы примеров демонстрирует скриншот в начале статьи.

А теперь собственно о виджетах. SVG-виджеты оформлены в виде пяти классов: cbutton, ibutton, mbutton, cmenu и cframe, которые объединены в пакет svgwidgets:

%#Загрузка пакета svgwidgetds
%package require svgwidgets
0.3.3
%

Убедиться в том, что svg-виджеты стали доступны (классы ::cbutton, ::ibutton, ::mbutton, ::cmenu, cframe), можно выполнив следующую команду:

 % foreach class [info class instances oo::class] {puts $class}
::oo::object
::oo::class
::oo::Slot
::cbutton
::ibutton
::mbutton
::cmenu
::cframe
%

Создание svg-виджетов практически ничем не отличается от создания классических виджетов в tcl/tk. Если вспомнить как создаются объекты того или иного класса при объектно-ориентированном программировании в tcl/tk, то окажется, что есть два способа. Различие этих способов состоит в том, что в первом способе идентификатор создаваемого объекта назначает конструктор класса:

<имя класса> new <имя холста> [параметры объекта]

Во втором способе идентификатор объекта назначает программист:

<имя класса> create <идентификатор объекта> <имя холста> [параметры объекта]

В обоих случаях конструктор возвращает идентификатор созданного объекта.

Для уничтожения объекта используется метод destroy:

<идентификатор объекта> destroy

При уничтожении объекта удаляется и холст, на котором создавался виджет.

Виджеты могут создаваться как каждый на отдельном холсте, так и размещаться на одном холсте. В последнем случае должны дополнительно указываться координаты левого верхнего угла виджета (параметры -x и -y). В этой статье мы будем рассматривать случай, когда каждый виджет создается на отдельном холсте. Заливка холста, на котором будет создаваться виджет, задается параметром –background или -bg.

Начнем знакомство с svg-виджетами с базового класса cbutton. В этом классе можно создать виджеты следующих типов (параметр -type): rect, round. ellipse, square, circle, check, radio, frame. По умолчанию создается виджет типа rect:

%cbutton new .but1 –text {Прямоугольник}
::oo::Obj58
#Посмотреть тип созданного виджета
%::oo::Obj58 config –type
rect
#Удаляем созданный виджет
%::oo::Obj58 destroy
%

Ниже представлен скрипт, который демонстрирует создание виджетов класса cbutton, за исключением типов radio и check. В скрипте демонстрируется создание виджетов типа frame и размещение в нём виджетов типа rect, round. ellipse, square, circle:

#скрипт №1
#загрузка пакета svgwidgets
package require svgwidgets
#установка геометрии главного окна
wm geometry . 500x400+100+50
#создаем svg-виджет класс cbutton и типа frame 
set wfr [cbutton new .fr -type frame -fillnormal snow -strokenormal red]
#размещаем фрейм на главном окне, используя метод pack в классе cbutton
$wfr pack -in . -fill both -expand 1 -padx 1c -pady 1c
#Создаем виджеты кнопок rect, round. ellipse, square, circle
set i 0
foreach tbut  [list rect round ellipse square circle ] {
	set but$i [ eval cbutton new .but$i  -type $tbut -command \{puts [set tbut]\} -text $tbut]
#Метод canvas в проекте svg-виджетов возвращает идентификатор (имя) холста,
#на котором размещается виджет
	[set but$i] pack -in [$wfr canvas] -pady {5m 0}
	incr i
}

Для получения свойств (параметров) отдельного виджета служит метод config. Например, для получения всех свойств виджета типа round в рассматриваемом примере достаточно выполнить команду вида:

%$but1 config
-text round -strokepress #dadada -strokeenter cyan -command {puts round} -stroke #dadada press 0 -fillnormal gradient1 -strokewidth 1 -strokenormal #dadada -state normal -rx 13.000000000000002 -fontsize 11.338582677165354 -relcom 0 -ry 0 -displaymenu release -image {} -fillpress green -textfill black -fillenter skyblue -compound none -ipad {3.779527559055118 3.8004301075268843 3.8628571428571488 3.8628571428571488} -fontweight normal -rotate 0 -width 94.0 -fontfamily {DejaVu Sans} -isvg {} -height 26.000000000000004 -type round
%

Назначение параметров достаточно прозрачное. Отдельного пояснения требует работа с иконками (параметры -image, -isvg, -compound, -ipad), о них мы поговорим в следующей части.

Сразу отметим, что заливка виджетов (параметры -fillpress, -fillenter, -fillnormal) может быть как одноцветной, так и градиентной. О градиентной заливке расскажем в отдельной статье. Параметр -fillpress определяет заливку виджета при нажатой кнопки мыши, -fillenter – при наведении курсора мыши на виджет, -fillnormal – при обычном состоянии.

Оконтовка виджета (параметры -strokenormal, -strokepress, -strokeenter) может быть только одноцветной. При этом можно регулировать прозрачность как заливки (параметр -fillopacity), так и окантовки (параметр -strokeopacity). По умолчанию виджеты создаются непрозрачными. Уровень прозрачности задается от 0 до 1.

Метод config служит также для получения текущего значения того или иного атрибута или установления нового значения:

<экземпляр объекта> config <атрибут> [<новое значение атрибута>]

При создании виджетов класса cbutton с типом check и radio (аналоги классических виджетов checkbutton и radiobutton) дополнительно должен задаваться параметр -variable с указанием глобальной переменной, в которой будет сохраняться ее значение. Для виджета типа check значение 1 будет указывать на то, что кнопка была нажата, а 0 – кнопка отжата. Для виджета типа radio задается еще параметр –value со значением, которое будет принимать переменная при нажатии на эту кнопку.

Кстати, получить список всех доступных методов можно выполнив команду вида:

<экземпляр объекта> methods

Для получения списка экземпляров отдельного класса можно воспользоваться командой вида:

info class instances <имя класса >

В последующем мы рассмотрим использование иконок, в том числе и из svg-файлов, а так же покажем как работает масштабирование, создание выносок (callout-ов) и другое. А здесь можно попробовать получить текущий список иконок:

%image names
::tk::icons::information ::tk::icons::warning
%

и одну из этих иконок ::tk::icons::warning назначить виджету, который имеет тип rect (переменная but0):

%$but0 config -image ::tk::icons::warning
%

Иконки доступны для виджетов класса cbutton типа rect или square.



Проверено: hobbit ()
Последнее исправление: TclTk (всего исправлений: 6)

троллейбус-из-хлеба.жпг

Из статьи непонятно в каких случаях оно лучше чем другие более популярные и распространенные тулкиты

intel ★★
()
Последнее исправление: intel (всего исправлений: 1)
Ответ на: комментарий от intel

Уточните, пожалуйста, какие другие тулкиты имеются в виду? Здесь речь идет о tcl/tk. Хотя в мыслях иногда проскальзывает мысль о реализации svg-виджетов для Tkinter в Python-e.

TclTk
() автор топика
Ответ на: комментарий от TclTk

Зачем нужен Tcl/Tk с костылем в виде svg виджетов в принципе? Чем он лучше Qt, GTK или Flutter? Не троллинга ради. Действительно непонятен смысл его использования в наши дни

intel ★★
()
Ответ на: комментарий от intel

Вы спрашиваете зачем нужен tcl/tk? Вопрос риторический. И ответ будет длинноват. Начать ответ хочу с цитаты из слов Брайана Кернигана,которую мне посчастливилось найти:

Tcl/Tk придает работе магическую продуктивность, за несколько часов можно достигнуть тех же результатов, что за дни или недели при разработке на C или C++… Tk весьма эффективен для большинства приложений, многие элементы интерфейса (виджеты) реализованы настолько хорошо, что остается только удивляться, как подобная работа могла быть выполнена так качественно… Удачным кажется и то, что разделение задач между Тсl и С/С++ осуществляется достаточно легко, надо только знать, какой инструмент лучше справляется с задачей… Расширение системы дополнительным Tcl-кодом, загружаемым напрямую в Tcl-библиотеку приложения, в полном согласии с оригинальной идеей Остераута, повышает эффективность программы, в целом, упрощает ее структуру и улучшает мобильность… Я не уверен, что Тсl мог бы выжить как самостоятельный продукт - у него слишком много конкурентов. Но у сочетания Tcl/Tk в Unix-мире нет конкурентов… Система исключительно надежна, очень хорошо документирована… свободно доступна… безукоризненно высокого качества

Лично для меня Брайан Керниган не менее авторитетен чем Ричард Столлман, на которого ссылаются когда хотят принизить tcl/tk. В этой связи приведу один комментарий по этому поводу:

Столлман высказался в духе, что Tcl не подходит для больших проектов. Если прочесть критику полностью (а это достаточно известный holywar), то ясно что Tcl для него - средоточие контекстно-зависимых языков и свободных грамматик. Как фанату лиспа ему немного обидно что есть язык даже в теории более гибкий. Он (да и многие сейчас), кстати, тогда так и недопёр, что lisp и tcl, несмотря на всю похожесть, принципиально разные языки и их сравнивать всё равно что сравнивать кислое с мягким. К тому же Столлман явная противоположность с Остерхаутом (автором tcl) - Ричард идеалист и анархист, Джон прагматик и консерватор. Первый всю жизнь обретается по халявным фондам и публично пиарится, второй в корпоративном секторе и тихо диктаторствует над проектами. Так что личные отношения сыграли не последнюю роль. Вести проекты с Tcl действительно ‘внезапно’ сложно ;-) Серьёзное использование Tcl подразумевает создание собственного языка, максимально удобного для разработчика и конкретной задачи. А чтобы ‘язык’ всех частей проекта был одинаково понятен всем - сами разработчики должны быть примерно одинаковой(высокой) квалификации и проект должен вестись централизованно и жёстко. Можно сказать Тикль максимально гибок и лёгок в использовании и столь же строг в ведении проектов.

И такая позиция мне импонирует.

TclTk
() автор топика
Ответ на: комментарий от TclTk

Столлман высказался в духе, что Tcl не подходит для больших проектов

Он же пытался пропихнуть гнутую альтернативу. Так как лицензия у tcl не gplугодная

vbcnthfkmnth123 ★★★★★
()
Ответ на: комментарий от TclTk

Tcl/Tk придает работе магическую продуктивность, за несколько часов можно достигнуть тех же результатов, что за дни или недели при разработке на C или C++… Tk весьма эффективен для большинства приложений, многие элементы интерфейса (виджеты) реализованы настолько хорошо, что остается только удивляться, как подобная работа могла быть выполнена так качественно… Удачным кажется и то, что разделение задач между Тсl и С/С++ осуществляется достаточно легко, надо только знать, какой инструмент лучше справляется с задачей…

Да, но сейчас есть Dart/Flutter. Впрочем, я понимаю что производительность у Tcl/Tk выше, при этом веса и зависимостей меньше. Однако для большинства современных устройств ни то, ни другое не является критичным. Верно ли я понимаю что ниша Tcl/Tk в наши дни по сути сводится к IoT-устройствам с GUI, с серьезными ограничениями по постоянной и оперативной памяти?

intel ★★
()
Последнее исправление: intel (всего исправлений: 1)
Ответ на: комментарий от intel

tcl/tk есть практически везде. Используйте где хотите. Мне нравится tcl/tk на Android - Androwish, легко и просто!

TclTk
() автор топика

это ужасно... но круто, самому нравится tcl.

demidrol ★★★★★
()

Поясни

Тут каждый svg-виджет рисуется на собственном canvas’e или все svg-виджеты на одном canvas’e?

futurama ★★★★★
()
Последнее исправление: futurama (всего исправлений: 1)
Ответ на: комментарий от futurama

Если имя canvas уникально для виджета, то виджет создается на отдельном холсте.

Можно создать сначала canvas, а затем на нем создавать виджеты, указываия имя созданного холста, не забывая указывать и координаты для размещения на холсте виджета.

Посмотри пример - скрипт_button_Xолст.tcl , где все виджеты создаются на одном холсте. Есть ещё пример - скрипт_menu_Холст.tcl

TclTk
() автор топика
Последнее исправление: TclTk (всего исправлений: 1)
Ответ на: комментарий от intel

Чем он лучше Qt, GTK или Flutter?

Можно написать программу в 2005-м году и она будет работать в 2025м. А вот чтобы собрать программу на Qt4 или Gtk2 — нужно поплясать с бубном.

ugoday ★★★★★
()
Ответ на: комментарий от TclTk

К тому же Столлман явная противоположность с Остерхаутом (автором tcl) - Ричард идеалист и анархист, Джон прагматик и консерватор. Первый всю жизнь обретается по халявным фондам и публично пиарится, второй в корпоративном секторе и тихо диктаторствует над проектами.

всю жизнь обретается по халявным фондам и публично пиарится

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

Я таки напомню, что Столлман сформировал культуру свободного ПО, без Столлмана не было бы GNU/Linux, который мы знаем, и которым вовсю пользуются те самые корпорации в том числе. Если для автора цитаты, которая Вам импонирует – это «всю жизнь обретается по халявным фондам и публично пиарится», пусть будет так, это вопрос личной порядочности автора цитаты. Это раз.

Ну и перейти с преимущественно технических аргументов RMS против Tcl (насколько я понимаю, речь про это) на личность автора аргументов – это, конечно пять. Это тоже пусть будет на совести автора копипасты и тех, кому она импонирует. Это два. Честный человек привёл бы именно адекватные технические же контраргументы (и они вполне могут быть разумными, я позицию RMS не считаю единственно правильной).

Против самих Tcl и Tk ничего не имею, если что. Очень интересная концепция. Пытался лет 20 назад ваять на них какие-то хеллоуворлды, но потом всё-таки сбежал на плюсы с кутями.

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 2)
Ответ на: комментарий от Dr64h

Может поэтому:

FLTK не использует сложных макросов, препроцессоров и продвинутых возможностей языка C++ (шаблоны, исключения, пространства имен).

А чуть серьёзнее, разнообразие укрошает наш мир

TclTk
() автор топика

Не, ему лучше бы пошла тема Редмонд. Или что то такое, в духе интерфейча Homm 2/3. А если надо прям современно - тогда косплеить метроприложения win10 где нет ничего кроме одноцветных прямоугольников в вакууме.

kirill_rrr ★★★★★
()

Ваше остроумное решение привлечь внимание к TclTk вырвиглазной картинкой сработало.

Какая, кстати, сейчас у TclTk ниша?

Раньше я видел что при помощи него решали вопрос кроссплатформенных GUI, а сейчас что?

gagarin0
()

Сам я использовал tcl не так не давно, в eggdrop, когда надо было сделать гейт twitch chat <-> vector.dev <-> telegram

Вышло довольно быстро, но как выяснилось что последний релиз в 2024 году eggdrop все еще протекает как старое корыто, хаха https://github.com/eggheads/eggdrop/issues/1545

gagarin0
()
Ответ на: комментарий от Dr64h

Ты не понимаешь

Вы не угадали, я как раз наоборот, понимаю и люблю Кандинского, по этому я могу точно сказать что этот набор конкретных «фигур», их расположение и выбор цвета - вырвиглазная мазня, поверьте мне на слово

gagarin0
()

чтобы посмотреть, как выглядит приложение нам базе svg-виджетов.

На.

В этой статье мы буде рассматривать

Будем.

и размещение в нём виджетов типов rect, round

Типа.

При создании виджетов класса cbutton типов check и radio

С типом.

Для получения списка экземпляров отдельного класс можно

Класса.

и одну из них установить в виджету типа rect

Виджет.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

Спасибо!!! Не соображу как теперь поправить в статье. Может и здесь подскажете?! Владимир

TclTk
() автор топика
Ответ на: комментарий от maxcom

Фу! Разобрался! Нашёл! Спасибо! Начал править! Огромное спасибо.

TclTk
() автор топика

Мне понравилось что есть рамки у окон. Я к ним привык еще со времён Windows 8, и очень сгрустнул когда в более новых Виндах убрали рамки окон.

bonta ★★★★★
()
Ответ на: комментарий от TclTk

«установить в виджету», конечно, было неправильно, но исправленный вариант тоже получился как-то не по-русски.

Я поправил на «назначить виджету типа…».

P.S. Мать чувашского народа на скриншоте желает автору и его пет-проекту удачи?

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 2)
Ответ на: комментарий от hobbit

Текст поправил. А Мать чувашского народа всегда со мной. Хотя сам я русский, но чувашский народ уважаю, а Чебоксары по моему разумению, где стоит этот монумент, лучший город Земли, несмотря ни на что. Спасибо.

TclTk
() автор топика
Ответ на: комментарий от Dr64h

C++ → проблемы с использованием из других языков → не нужно.

ugoday ★★★★★
()

Тема - огонь вообще!

Но я в последнее время подумываю о том, а не может ли клиент сам отрисовывать интерфейс в каких ему угодно виджетах основываясь исключительно на данных, которые необходимо редактировать?

Так-то набрасывание виджетов на 2D-формочку в автоматическом режиме не кажется какой-то неосуществимой задачей, зато насколько можно было бы и веб преобразить и вообще весь пользовательский опыт как на десктопе, так и на мобильных устройствах…

unDEFER ★★★★★
()

Можно как пользователь художнику?

Фоны должны быть пастельными, т.е. блёклыми, иначе глазки вытекают. Яркие и ядовито-яркие цвета лишь для предупреждений «ты шо, стервец, творить удумал?»

Границы окон должны быть, но должны быть другого цвета, нежели рамки или фон, иначе всё сливается, не у всех «глаз, как у орла».

По расположению кнопок ничего не скажу, тут надо поработать с прогой для оценки удобства.

P.S. И лично мой вкус: желательно предусмотреть возможность смены шрифта «без засечек» на «с засечками». Выросшим на «книжных шрифтах»… в бумажных книгах оно комфортнее.

mister_VA ★★
()
Ответ на: комментарий от mister_VA

Это вы про скриншот в начале статьи?

Он демонстрирует возможности, а все остальное настриавается через опции.

Например. шрифт настраивается параметрами -fontslant, -fontweight, -fontfamily. А еще есть для текста параметры -textfill, textstroke, -textstrokewidth, -textfillopacity, -textstrokeopacity.

Аналогично настраивается границы и задивка виджета. Цвет может быть как однотонный, так и градиентный.

Всё как принято в svg-графике. Всё можно на тех же примерах, которые есть на github

TclTk
() автор топика
Ответ на: комментарий от MirandaUser2

Я с вами вполне согласен. Можно и на классических виджетах tk, если постараться, сделать приличный интерфейс.

TclTk
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.