LINUX.ORG.RU

Статьи «Разработка»

Tcl/tk. GUI на SVG-виджетах. Поддержка SVG-файлов. Часть II

Прежде чем перейти к рассмотрению svg-файлов, хотелось бы остановиться на самом интерпретаторе tcl/tk. Отвечая на один из вопросов, заданных после публикации первой части, я написал, что рассматриваемый проект успешно работает и на tcl/tk версии 9.0.1.

Мне захотелось, чтобы вместе с публикацией второй части статьи был выложен и дистрибутив графического интерпретатора tclexecomp на базе девятой версии tcl/tk. Однако выпуск версии tclexecomp для tcl/tk-9 задерживается и было решено собрать дистрибутив самостоятельно. Уже имея опыт сборки проекта Bawt для tcl/tk-9.0.1, удалось после нескольких дней работы собрать и дистрибутив tclexecomp с tcl/tk-9.0.1, с включёнными в него пакетами проекта svgwidgets. И всё было замечательно, все тестовые примеры работали. Но тут случайно мною была на клавиатуре нажата клавиша Backspace и произошел крах интерпретатора. После проверки остальных клавиш выяснилось, что аналогичный эффект происходит при нажатии клавиш Left и Right. Сначала я подумал, что это мои косяки, но решил проверить работу этих клавиш на виджетах text, entry и ttk::entry, в которых для редактирования текста используются эти клавиши. И тут выяснялось, что нажатие на эти клавиши приводит к краху интерпретатора wish9.0, т. е. собранная версия графического интерпретатора tclexecomp здесь ни при чём.

Честно говоря, я не стал проверять работу этих клавиш на первой версии tcl/tk-9.0.0. Первым порывом было написать письмо разработчикам tcl/tk, но прежде я решил посмотреть, как идут дела у разработчиков с подготовкой очередного релиза. И здесь меня ждал приятный сюрприз. В файле изменений для tk-9.0.2 присутствует такая запись: Backspace crashes 9.0 interpreter on FreeBSD.

Это было то, с чем столкнулся я. Правда здесь речь идёт о FreeBSD, а у меня Linux, но я решил проверить. Проверка дала положительный результат и больше проблем с клавиатурой я не наблюдал. Собранный интерпретатор со всеми пакетами svgwidgets под именем tclexecomp64_902_Lin64 добавлен в проект TkSVGWidgets на GitHub-е в папку tclexecomp902. Всем, кто будет тестировать проект, необходимо его скачать заново с GitHub. А теперь возвращаемся к основному материалу.

SVG-файлы представляют собой текстовые файлы с расширением .svg, содержащие xml-код, описывающий изображения в виде геометрических примитивов: линий, кривых, фигур, текста и т.д.

В tk-9.0 добавлена частичная поддержка svg-графики, которая позволяет использовать svg-иконки в GUI. Для этого сначала создается изображение:

image create photo [<идентификатор изображения>] [-format {svg [-scale <масштабирование> | -scaletowidth <ширина> | -scaletoheight <высота>]} 

Данный оператор всегда возвращает идентификатор изображения. Параметр scale задает масштаб изображения относительно исходного. Параметр scaletowidth указывает требуемую ширину изображения. Пропорционально изменению ширины будет установлена и высота изображения. Аналогично работает и параметр scaletoheight. Менять размер изображения можно и командой configure:

<идентификатор изображения> configure -format {svg [-scale <масштабирование> | -scaletowidth <ширина> | -scaletoheight <высота>] 

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

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

Для демонстрации запустим интерпретатор tclexecomp64_902_Lin64.

После запуска интерпретатора и загрузки пакета svg2can достаточно выполнить несколько команд, чтобы на холсте появилось изображение из файла svgimages/Action_launch.svg:

#Загружвем пакет svg2can
package require svg2can
#Создаем окно проекта
toplevel .t -background cyan
#Геометрия окна
wm geometry .t  380x640
#Создаем холст tkp::canvas
tkp::canvas .t.c -bg yellow -width 500 -height 450
#Размещаем холст в окне
pack .t.c -fill both -expand 1
#Размещаем на холсте картинку из svg-файла
set idsvg [svg2can::SVGFileToCanvas .t.c svgimages/Action_launch.svg]
winfo class .win.c
#Координаты картинки на холсте
set coordsid [.t.c bbox $idsvg]

В данном примере для отображения на холсте картинки используется команда svg2can::SVGFileToCanvas из пакета svg2can, которая имеет следующий формат:

svg2can::SVGFileToCanvas <tkp-холст> <путь к svg-файлу>

Xml-код картинки необязательно должен храниться в файле, его можно задавать явно в виде константы или как значение tcl-переменной. В этом случае используется команда следующего вида:

svg2can::SVGXmlToCanvas <path-холст> <xml-код>

Команды svg2can::SVGFileToCanvas и svg2can::SVGXmlToCanvas при успешном выполнении возвращают идентификатор группы (далее просто группа), в которой сгруппированы все элементы картинки. Чтобы получить все идентификаторы элементов картинки, достаточно выполнить команду:

<холст с картинкой> children <идентификатор группы>

Очевидно, что рисунок на холсте должен располагаться в определенном месте и иметь определенные размеры. Для перемещения картинки в соответствующие координаты и установления требуемого размера служит команда копирования группы:

svg2can::copy <холст с картинкой> <холст назначения> <группа> [<параметры>]

Эта команда копирует заданную картинку (<холст с картинкой> и <группа>) на указанный <холст назначения> и возвращает идентификатор группы на холсте назначения. Естественно, копирование может производиться и в рамках одного холста. После копирования оригинал может быть (если он больше не потребуется) уничтожен:

<холст с картинкой> delete <идентификатор группы>

Координаты клона на заданном холсте задаются списком параметров:

-x <координата по оси X>
-y <координата по оси Y>
-width <ширина картинки>
-height <высота картинки>

Для примера клонируем нашу картинку, при этом ширину картинки увеличим в полтора раза, а высоту увеличим в три раза и расположим справа от эталона. Размеры оригинала определим, выполнив команду bbox:

#Вычисляем координаты орининала
lassign [.t.c bbox $idsvg] x0 y0 x1 y1
#Создаем клон ракеты
::svg2can::copy .t.c .t.c $idsvg -x $x1 -y $y1 -width  [expr {($x1 - $x0) * 1.5}] -height [expr {($y1 - $y0) * 3}]

Результат можно увидеть в центре скриншота, в начале статьи.

Итак, svg-изображение характеризуется двумя параметрами: именем холста, на котором оно размещено, и номером группы на этом холсте. SVG-изображения, так же как и классические изображения (image) могут использоваться как иконки в виджетах классов ibutton и cbutton. В классе cbutton иконки применимы к типам rect и square. Классические иконки задаются их идентификаторами, а svg-изображения задаются парой (списком)

-image | -isvg [list <svg-холст> <идентификатор группы>] 

или

-image | -isvg "<svg-холст> <идентификатор группы>"

Ниже представлен код, который добавляет кнопку «Старт» с иконкой в виде ракеты:

#Загружаем пакет svgwidgets
package require svgwidgets
#Устанавливаем высоту холста
.t.c configure -height 520
#Создаём кнопку «Старт» 
set idlauch [cbutton new .t.b2 -text Старт -image ".t.c $idsvg" -rx 10 -strokewidth 3]
#Устанавливает характеристика шрифта
$idlauch config -fontsize 29 -textfill red -textstroke yellow -fontweight bold
#Размещаем иконку в окне
pack  [$idlauch canvas] -fill both -expand 1 -padx 2c -pady 5m

Можно «поиграться» геометрией главного окна (например, перемещая правый нижний угол окна) и посмотреть как будет видоизменяться иконка с ракетой.

На Linux в каталоге /usr/share/icons можно найти много svg-файлов. Для их просмотра были написаны тестовые утилиты svgTestOrigToSVGWIDGET_Pack.tcl и svgtesttocan.tcl, которые находятся в каталоге examples.

К svg-изображениям можно применять различные трансформации (перемещение, масштабирование, поворот, смещение по осям X и Y). Увидеть, как это работает, можно, запустив утилиту examples/svgFileToCan.tcl. Результат работы этого скрипта можно видеть в правой нижней четверти скриншота в начале статьи.

Для комплексной демонстрации возможностей проекта svgwidgets в хранилище проекта на GitHub-е добавлен каталог examples/CryptoArmPKCS_Test, в котором лежит демонстрационный код криптографической утилиты cryptoatmpkcs_svg для работы с электронной подписью. Для ее запуска следует воспользоваться интерпретатором tclexecomp64_902_Lin64:

$tclexecomp64_902_Lin64 examples/CryptoArmPKCS_Test/mainguipkcs_svg.tcl

Стартовую страницу этой утилиты можно видеть в правой верхней четверти скриншота в начале статьи.

 , , , ,

TclTk
()

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

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

( читать дальше... )

 , , , ,

TclTk
()

Что почитать C++ программистам

Предлагаю вашему вниманию две бесплатные электронные книги. Первая написана мной: «Вредные советы для C++ программистов» (PDF-формат). Это переработанный под печать вариант «60 антипаттернов для С++ программиста». Если вы уже читали 60 антипаттернов, то, пожалуй, читать новый вариант смысла нет. А если нет, то рекомендую — это и возможность местами улыбнуться, и польза.

Теперь про вторую книгу: «Путеводитель C++ программиста по неопределённому поведению». Здесь я был редактором, автор: Дмитрий Свиридкин. Книга опубликована частями, ссылки на которые приведены ниже. Сейчас Дмитрий перерабатывает материал под книжное издание, но это отдельная история.

  1. Часть 1: предисловие, что такое неопределённое поведение, и как оно проявляется, сужающие преобразования и неявное приведение типов.
  2. Часть 2: переполнение целых знаковых чисел, числа с плавающей точкой, integer promotion, char и знаковое расширение.
  3. Часть 3: висячие ссылки, string_view, синтаксический сахар с ложкой дёгтя (range-based for), self-reference, std::vector и инвалидация ссылок.
  4. Часть 4: списки захвата лямбда-функций, кортежи, внезапная мутабельность, неявные ссылки, use-after-move, lifetime extension.
  5. Часть 5: Most Vexing Parse, неконстантные константы, семантика перемещения, std::enable_if_t против std::void_t, забытый return.
  6. Часть 6: эллипсис и функции, operator [], iostreams (счастливой отладки!), оператор запятая, function-try-block, типы «нулевого» размера.
  7. Часть 7: NULL-терминированные строки, std::shared_ptr, (не)явное приведение типов, как передать стандартную функцию и ничего не сломать.
  8. Часть 8: бесконечные циклы и проблема остановки, рекурсия, ложный noexcept, переполнение буфера.
  9. Часть 9: (N)RVO vs RAII, разыменование нулевых указателей, static initialization order fiasco, static inline, нарушение ODR, зарезервированные имена.
  10. Часть 10: тривиальные типы и ABI, неинициализированные переменные, С++20 unbounded ranges, невиртуальные виртуальные функции, VLA.
  11. Часть 11: невалидные указатели, placement new для массивов, data race, повторный захват mutex, сигнало(не)безопасность, как сделать всё правильно и уйти в deadlock.
  12. Часть 12: std::vector::reserve и std::vector::resize, невыровненные ссылки, время жизни и смерти, статический анализ и UB, заключение.

И последнее: если пропустили, в конце 2024 года, как всегда, вышла подборка про самые интересные из найденных нами багов: Топ-10 ошибок в C и C++ проектах за 2024 год.

 ,

Andrey_Karpov_2020
()

image viewer simply на bash

image viewer simply на bash

Хочу представить простенький просмотрщик изображений на bash. Накропал его сам и может он не имеет практического применения,но все же. Конечно там возможно много сделать лучше и проще. Как говорится как есть))

#!/bin/bash

export tmp_num="/tmp/numbegin"
[ ! -f "$tmp_num" ] && echo "1" > "$tmp_num"
export file_image="/tmp/file_image" 
[ ! -f "$file_image" ] &&  find / -xdev  -type f -name "*.png" -or -name "*.svg"  -or -name "*.jpg"  >  /tmp/file_image  
 
export col_image=$(cat $file_image | wc -l)
export max_stroke=$(grep -c $ "$file_image" | (read a; echo $(( ($a/300)*300+1 ));))
export FILE_PATH=$(realpath "$0") 
export catnum=$(cat "$tmp_num")
  function IMAGE_FILE () { 
begin="$1" 
begin="$catnum"
IFS=$'\n'
i="$begin"  
 
for file_name in $(sed -n "${begin},$((${begin} + 299))p" $file_image) 
  do
#size=$(exiv2 $file_name 2>/dev/null | awk ' NR==2 {printf("%.2f", sum ($4 / 1024)); print "Kb"}; NR==4 {print $4 "x" $6 "px"}' | tr '\n' ' ') --text=\"$size\"yad  --undecorated --image=\"$file_name\" --text=\"$file_name\" --selectable-labels  
 if (( "$i % 30" == 0 )) && [[ "$i" -le $((${begin} + 299-30)) ]] ; then num="</hbox><hbox>"; else num=""; fi
  echo "<button tooltip-text=\"$i $file_name\"><input file>\"$file_name\"</input><action>xdg-open  \"$file_name\"</action><height>30</height><width>30</width></button> $num"
  i=$((i + 1))
done
}
export -f IMAGE_FILE 
 
export MAIN_DIALOG_IMAGE='<window window-position="1" title="Галерея  bash"><vbox><hbox>'`IMAGE_FILE $begin`'</hbox><hbox space-expand="true" space-fill="true">
<button label="start">
<action>echo "1" > "$tmp_num"</action>
<action>$FILE_PATH $begin &</action></button>

<button label="'"$catnum"' prev">
<action>if [ "$catnum" -gt 1 ]; then begin=$(($catnum - 300)); echo "$begin" > "$tmp_num"; else begin=1; echo "1" > "$tmp_num"; fi</action>
<action>$FILE_PATH $begin &</action></button>

<button label="next '"$catnum"' - '"$(( $catnum + 299 ))=$col_image"'">
<action>if [[ "$catnum" -lt "$max_stroke" ]]; then begin=$(($catnum + 300)); echo "$begin" > "$tmp_num"; else begin=1; echo "1" > "$tmp_num"; fi</action>
<action>$FILE_PATH $begin &</action></button>
</hbox>
</vbox></window>'

gtkdialog --program=MAIN_DIALOG_IMAGE &
 
 PID_SUM=$(ps | grep "MAIN_DIALOG_IMAGE" | grep -v grep | awk '{print $1}' | wc -l) 
  PID=$(ps -eo pid,cmd | grep "MAIN_DIALOG_IMAGE" | grep -v grep | awk '{print $1}' | head -1)
  [ "$PID_SUM" -gt 1 ] && kill $PID
[ "$catnum" -ge "$max_stroke" ] && echo "1" > "$tmp_num" && $FILE_PATH $begin &

Хотел чтобы список был больше,но long arg list не дал это сделать. ps Не имею ни какого образования в программировании.

 , ,

nik120s
()

Делаем из Vim IDE

Делаем из Vim IDE

В стародавние времена когда деревья были большими, трава зеленее, а мороженное стоило по 10 копеек, на Земле жили динозавры, и эти динозавры программировали в Vim.

( читать дальше... )

 , ,

rtxtxtrx
()

Настройка VS Code для работы с Python

Настройка VS Code для работы с Python

VS Code — это мощный инструмент для разработки на Python, который легко настроить для работы с такими полезными утилитами, как pylint, black и isort. Эти инструменты помогут поддерживать чистоту кода, единый стиль и упорядоченность импортов. Для поиска и устранения ошибок пригодится встроенный отладчик debugpy, обеспечивающий удобный процесс дебага. В дополнение ко всему можно подключить искусственного помощника для ускорения написания кода. В этой статье мы рассмотрим установку и настройку этих инструментов, а также их интеграцию с VS Code.

( читать дальше... )

 , , , ,

rtxtxtrx
()

Настройка Visual Studio Code для работы с LLama

Настройка Visual Studio Code для работы с LLama

В этой статье я расскажу как развернуть локальные аналог Chat-GPT и настроить VS Code для работы с ним.

( читать дальше... )

 , , ,

rtxtxtrx
()

Geany — между редактором и IDE

Описана установка и настройка текстового редактора Geany, в том числе для редактирования кода.

( читать дальше... )

 

MOPKOBKA
()

Создание пакетов для Python-приложений с помощью pyproject.toml

Создание пакетов для Python-приложений с помощью pyproject.toml

Вам больше не нужны poetry и pipenv - достаточно лишь pyproject.toml.

( читать дальше... )

 ,

rtxtxtrx
()

Разработка сетевой библиотеки на C++20: интеграция асинхронности и алгоритма Raft (часть 2)

Разработка сетевой библиотеки на C++20: интеграция асинхронности и алгоритма Raft (часть 2)

Эта статья является продолжением предыдущей публикации, в которой описывается разработка сетевой библиотеки на C++20. В данном продолжении акцент сделан на более детальном описании разработки алгоритма Raft и его интеграции с сетевой библиотекой.

( читать дальше... )

 , , ,

Reset
()

Разработка сетевой библиотеки на C++20: интеграция асинхронности и алгоритма Raft (часть 1)

Разработка сетевой библиотеки на C++20: интеграция асинхронности и алгоритма Raft (часть 1)

Введение

С годами работы в области распределённых систем, я понял, что мой опыт не будет полным без реализации алгоритма Raft. Это осознание побудило меня к действию: я решил создать свою реализацию, используя асинхронные возможности C++20.

( читать дальше... )

 , , , ,

Reset
()

Линукс, ассемблер и X11

Линукс, ассемблер и X11

Это текстовая версия моей статьи про разработку графического приложения на чистом ассемблере под линукс.

( читать дальше... )

 , ,

alex0x08
()

Проблемы надёжной доставки данных до постоянного хранилища и fsync()

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

( читать дальше... )

 , ,

firkax
()

Осваиваем STM32 снизу: часть 9 - подключаем libc

Часть 1 Часть 2 Часть 3 Часть 4 Часть 5 Часть 6 Часть 7 Часть 8 Часть 9

Часть 9: подключаем libc

libc это стандартная библиотека языка С. До сих пор мы избегали использования любых функций из стандартной библиотеки, если бы мы попробовали это сделать, то линкер выдал бы ошибку.

( читать дальше... )

 ,

vbr
()

Осваиваем STM32 снизу: часть 8 - используем CMSIS

Часть 1 Часть 2 Часть 3 Часть 4 Часть 5 Часть 6 Часть 7 Часть 8 Часть 9

Часть 8: используем CMSIS

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

( читать дальше... )

 ,

vbr
()

Осваиваем STM32 снизу: часть 7 - Hello world через UART

Часть 1 Часть 2 Часть 3 Часть 4 Часть 5 Часть 6 Часть 7 Часть 8 Часть 9

Часть 7. Hello world через UART

UART это протокол, по которому микроконтроллер может взаимодействовать с компьютером. Его можно использовать для печати отладочных сообщений, или для полноценного взаимодействия с программой, запущенной на компьютере. USART это что-то вроде расширенной версия UART, которую мы использовать не будем, в документации обычно используется именно этот термин.

( читать дальше... )

 ,

vbr
()

Осваиваем STM32 снизу: часть 6 - Мигаем с таймером

Часть 1 Часть 2 Часть 3 Часть 4 Часть 5 Часть 6 Часть 7 Часть 8 Часть 9

Часть 6. Мигаем с таймером

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

( читать дальше... )

 ,

vbr
()

Осваиваем STM32 снизу: часть 5 - Мигаем на C

Часть 1 Часть 2 Часть 3 Часть 4 Часть 5 Часть 6 Часть 7 Часть 8 Часть 9

Часть 5: Мигаем на C

Эта часть будет комбинацией частей 3 и 4. Мы перепишем код из части 3 на C, используя «инфраструктуру» для сборки из части 4 и познакомимся с некоторыми не всегда очевидными моментами, которые надо помнить при работе с микроконтроллером из кода на C.

( читать дальше... )

 ,

vbr
()

Осваиваем STM32 снизу: часть 4

Часть 1 Часть 2 Часть 3 Часть 4 Часть 5 Часть 6 Часть 7 Часть 8 Часть 9

Часть 4: Начинаем работать с C

Знание ассемблера важно, но многие программы разумней писать на C. В этой части мы напишем простую программу на C, скомпилируем её, исследуем получившийся объектный файл, правильно скомпонуем и запустим. После этого ещё немного изучим gdb.

( читать дальше... )

 ,

vbr
()

Осваиваем STM32 снизу: часть 3 - мигаем светодиодом

Часть 1 Часть 2 Часть 3 Часть 4 Часть 5 Часть 6 Часть 7 Часть 8 Часть 9

Часть 3: мигаем светодиодом

Мигание светодиодом это традиционный hello world для микроконтроллеров. Это один из самых простых способов взаимодействия с окружающей средой без помощи отладчика. В этой части именно этим мы и займёмся.

Сразу оговоримся, что эта часть и далее уже очень сильно зависят от конкретного процессора и даже платы. Все адреса приведены со ссылками на reference manual, что должно помочь в переводе кода на другие процессоры.

( читать дальше... )

 ,

vbr
()