Tcl/Tk. Альтернативный файловый проводник для платформ Linux и Android
Чем дольше я пишу различные программы на tcl/tk, тем больше восхищаюсь его возможностями и продуманностью. Но была одна вещь, которая не давала мне покою до последнего времени. При разработке GUI часто приходится пользоваться файловым проводником (tk_getSaveFile, tk_getOpenFile или tk_chooseDirectory). И если на платформах Windows или OS X, загружается нативный файловый проводник этих платформ, то на платформах Linux загружается проводник от tcl/tk (ну нет в Linux нативного проводника):
Что не устраивает в этом проводнике? Это отсутствие в нем элементарных операций с папками/файлами — создать, уничтожить, переименовать. Нет, не подумайте в самом tcl все эти механизмы, естественно, реализованы, их просто нет в GUI проводника. Но в Linux это не так заметно. А вот на платформе Android проводник от Tcl/Tk вызывает массу неудобств:
Когда мы говорим про платформу Android, то имеем ввиду разработку приложений на Androwish.
А тут такие времена настали, самоизоляция и т.д. В итоге, родилась балалайка (так еще называют пакеты/package для tcl) tkfe (tk file explorer).
При разработке пакета tkfe учитывалось не только то, что необходимы хотя бы элементарные операции с файлами/каталогами, то и было желание иметь проводник не только в отдельном окне, но и в отдельном фрейме, который пользователь сам разместить по своему желанию в своем GUI. В проекте имеется комплексный пример по использованию пакета. Итак, скачиваем проект, заходим в папку ~//TkFileExplorer/samples и запускаем пример:
$wish tkfe_samplefull.tcl
Собственно пример наглядно демонстрирует все возможности пакета. Например, запустим проводник для выбора папки в отдельном окне:
Сам проводник имеет интерфейс на двух языках: русском и английском. Перевод осуществляется на лету при нажатии кнопки с флагом:
Помимо кнопки с флагом, имеется кнопка с инструментами (tools), при нажатии на которую высвечивается контекстное меню, что можно делать в текущем каталоге (создать каталог/файл) или с выделенным файлом/папкой (удалить/переименовать):
Любая из функций файлового проводника возвращает имя (подчеркиваю — ИМЯ) переменной (см. пример tkfe_samplefull.tcl), в которую будет записан путь к выбранному файлу или каталогу или которая будет пустая в случае отказа от выбора. После получения имени переменной остается ждать когда, будет получен какой-либо результат, например:
. . .
#Выбор файла для чтения
#Тип размещения проводника window - отдельное окно; frame - отдельный фрейм
set typew "window"
#Фильт для файлов
set msk "*.txt *.doc *.crt * .*"
#Каталог пользователя
set tekdir $env(HOME)
#Вызов файлового проводника
set vrr [FE::fe_getopenfile $typew $w $tekdir $msk]
#Ждем результата
vwait $vrr
. . .
Если вы используете тип размещения проводника frame, то необходимо позаботиться о его размещении на вашей картинке. Размещение может быть любым способом (grid, pack или place). Предпочтительным способом является все же метод place. При нем не стоит заботиться о переформатировании картинки, так как place в отличии от grid и pack, позволяет наложить фрейм поверх имеющейся картинки:
Если внимательно посмотреть на картинку, то можно заметить, что правый скриншот отличается от левого появлением на нем скрытых папок (имена начинаются с точки). Для показа скрытых кнопок надо включить кнопку с иконкой в виде глаза. Папки и файлы можно также сортировать по алфавиту, а файлы по размеру:
Когда проводник размещается во фрейме то также стоит позаботиться о блокировании посторонних кнопок (когда проводник размещается в окне, то об этом заботится балалайка tkfe).
В пакет tkfe включены две функции, которые делают недоступными (all_disable) или доступными (all_enable) виджеты в пределах заданного виджета:
proc all_disable {parent} {
set widgets [info commands $parent*]
foreach w $widgets {
catch {$w configure -state disabled}
}
}
proc all_enable {parent} {
set widgets [info commands $parent*]
foreach w $widgets {
catch {$w configure -state normal}
}
}
namespace export fe_getsavefile
namespace export fe_getopenfile
namespace export fe_choosedir
namespace export all_enable
namespace export all_disable
Однако я предпочитаю пользоваться функцикй tk busy. Это хорошо видно в примере:
Это теория. На практике пакет tkfe был использован в криптографическом АРМ на базе стандартов с открытым ключом cryptoarmpkcs. Теперь использование файлового проводника в этом приложении для платформы Linux выглядит следующим образом:
А вот проводник, размещенный во фрейме:
И, конечно, очень удобно стало работать с проводником на платформе Android:
Кто-то может спросить: А как же Windows или OS X? Да, все замечательно. Но как всегда на Windows — это проблема русификации, в нашем случае это использование кириллицы в именовании файлов и папок, а также использование обратной косой черты. Поэтому в код необходимо добавить следующие строки:
#Перекодируем путь из кодировки ОС
#Для MS Win это скорей всего cp1251
set tekdir [encoding convertfrom cp1251 $tekdir ]
#Заменяем обратную косую в пути на нормальную косую
set tekdir [string map {"\\" "/"} $tekdir]
Вот так выглядит проводник tkfe на платформе Windows:
Сам пакет и примеры его использования лежат здесь.