python

Tcl/Tk. Альтернативный файловый проводник для платформ Linux и Android

  • среда, 15 апреля 2020 г. в 00:26:49
https://habr.com/ru/post/497258/
  • Python
  • Графические оболочки
  • Разработка мобильных приложений
  • Разработка под Android
  • Разработка под Linux


Чем дольше я пишу различные программы на 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:



Сам пакет и примеры его использования лежат здесь.