Софт и утилиты
Сайт создан в системе uCoz
Приветствую Вас, Пробегающий мимо · RSS 25.04.2024, 06:33
Главная » Статьи » Компиляторы и программирование » ARM

Embedded NGL(); строим итерфейсы в QtDesigner

   

    В прошлой статье кратко описан состав библиотеки и показан пример добавления в библиотеку контроллера ЖК HX8352, «сегодня» будем строить интерфейсы в QtDesigner и использовать их совместно с библиотекой NGL. Почему QtDesigner? Ну потому что это мощный, универсальный и легко расширяемый инструмент.

    Итак, первое что нам понадобится это установленный Python 3 и Qt5.4.1, установка под Windows (под Linux все в принципе аналогично) займет несколько этапов, но мы ведь не боимся трудностей :)

  • Скачать и установить последний офф. релиз Python 3

  • Скачать и установить Qt5.4.1 (почему именно 5.4.1 ниже)

  • Сборка SIP

  • Сборка PyQt5.4.1

  • Установка ngl utils


Установка Python, Qt

С установкой Python 3 все просто:

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

 

Path

Перед сборкой необходимо прописать в Path две переменные:

C:\Qt\Qt5.4.1\5.4\mingw491_32\bin\

C:\Qt\Qt5.4.1\Tools\mingw491_32\bin\

Перезагружаемся.

Сборка SIP

Качаем исходники SIP - https://www.riverbankcomputing.com/software/sip/download , распаковываем, в терминале набираем:

python configure.py –platform win32-g++

и затем:

mingw32-make install

 

Сборка PyQt5

Аналогично, качаем исходники PyQt5.4.1, распаковываем, в консоли набираем:

python configure.py --spec win32-g++

Соглашаемся с лицензией:

Далее набираем:

mingw32-make install

И идем пить чай пока все не соберется :)

 

Установка ngl utils

Это последний шаг нашего вооружения инструментарием :) , тут все просто, в консоли:

pip install ngl_utils

Или качаем последние исходники с GitHub, распаковываем и:

python setup.py install

На этом все, инструментарий готов!

  

Cначала пройдемся по ngl utils и посмотрим чего там есть, а есть там несколько утилит:

ngluic  - утилита конвертации файлов ui из QtDesigner, это наш основной инструмент.

ngldes  - скрипт запуска QtDesigner с плагинами из пакета ngl utils

nglfcn - конвертер шрифтов, позволяет конвертировать любой системный шрифт в исходники понятные NGL.

nglfed - редактор шрифтов NGL, открывает сгенерированные утилитами ngluic и nglfcn СИ файлы, можно отредактировать любой символ/символы шрифта.

 

   

    Ну вот теперь можем приступит строить дизайны :), запускаем QtDesigner, в консоли (можно и ярлыком сделать при желании) :

ngldes

После запуска QtDesigner видим плагины NGL, на даный момент это:

  • NGL_Button
  • NGL_Bitmap
  • NGL_CheckBox
  • NGL_FillBar
  • NGL_GraphScale
  • NGL_Label
  • NGL_Line
  • NGL_Rect
  • NGL_SeekBar

Этот список легко расширить добавив свои виджеты, но это пока мы отложим на закуску, как и краткое описание уже имеющихся.

    Не буду останавливаться на самом процессе работы в QtDesigner, в сети полно инструкций, видео, и т. п., Раставляем виджеты, редактируем, при желании используем Layout и компоновку, все просто (: . Вот как у нас будет выглядеть тестовый дизайн - ui file:

Интерефейс готов, сохраняем и из этой папки набраем:

ngluic -u test.ui --verbose

(полный список ключей доступен по ngluic -h или ngluic --help)

После окончания работы конвертера в папке должна появится следующая структура подпапок и файлов:

code
    bitmaps
        файлы сгенерированных шрифтов
        fonts.h
    fonts
        файлы сгенерированных изображений
        bitmaps.h
    pages
        mainpage
            mainpage.c
            заголовочные файлы объектов
        pages.h

Можно вручную задать куда ложить сгенерированный код указав это параметром -d, например:

ngluic -u test.ui -d C://projects//ngl_test//ngl//outcode --verbose

Параметр --bmp-cmprs [ NONE, RLE, JPG, AUTO ] отвечает за то в каком формате будут сгенерированные изображения из ресурсов проекта QtDesigner, сжатие RLE может быть эффективней на небольших и малотоновых изображениях по сравнению с JPG, на больших конечно же предпочтительней использовать сжатие JPG. Для автоматического выбора метода сжатия под оптимальный размер достаточно указать --bmp-cmprs AUTO, в этом случае утилита сама определит как сжимать то или иное изображение исходя из оптимального размера. К слову метод сжатия RLE используется несколько модифицированный по сравнению с "классикой" - wiki, кодируются не только серии повторяющихся объектов, но и серии не повторяющихся, это дает в некоторых случаях большее сжатие за счет уменьшения дополнительной информации в закодированном изображении, в худшем сравнивается по эффективности с "классикой". Использовать RLE можно и отдельно в своих программах на python, просто имопртировав ngl_utils.rle, например:

from ngl_utils.rle import rlem_encode, rlem_decode

Кодировать можно не только списки байт/слов/текста но и любых других списков произвольных объектов.

Для сжатия JPG используется инструментарий Qt, дополнительный ключ --bmp-jpg 50 установит качество 50. Ключ --verbose "заставит" утилиту выдавать больше информации о ходе конвертации, там же будет и отчет по каждому изображению и чем оно сжато.
 

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

 
/**
******************************************************************************
* @file MainPage.c
* @author Neil Lab :: Left Radio
* @version v1.0.0
* @date 2015-11-27 19:09:01.983739
* @brief NGL Page MainPage sourse
******************************************************************************
**/

/* Includes ------------------------------------------------------------------*/

#include "NGL.h"
#include "fonts.h"
#include "bitmaps.h"
#include "mainpage_labels.h"
#include "mainpage_graphscales.h"
#include "mainpage_buttons.h"
#include "mainpage_seekbars.h"
#include "mainpage_fillbars.h"
 
 
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Extern functions ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void MainPage_Draw(void);
static void MainPage_Click(Coordinate data, NGL_TouchType type);
 
/* Private variables ---------------------------------------------------------*/
    NGL_Page MainPage = {
    { 0, 0, 480, 320 }, // [X0, Y0, X1, Y1]
    0, // ID
    0x18c3, // BackColor
    TRUE, // Exit allowed
 
    /* Objects pointers array (Buttons, Labels, FillBars, etc.) */
    {
      mainpage_buttons, 4,
      mainpage_labels, 19,
      mainpage_fillbars, 8,
      mainpage_seekbars, 1,
      mainpage_graphscales, 2,
    },
 
    MainPage_Draw, // Page draw function
    MainPage_Click, // Page click (or index change) function
};
 
/* Private functions ---------------------------------------------------------*/
/**
* @brief MainPage_Draw
* Draw page objects function
* @param None
* @retval None
*/
static void MainPage_Draw(void)
{
    /* Clear all screen */
    NGL_LCD_Clear_AllScreen(0x18c3);
 
    /* Draw all static graphics primitive, labels, etc. */
    NGL_GP_DrawFillRect(5, 6, 119, 26, 0x83, DRAW, 0x83);
    NGL_Font_DrawString(20, 9, 0xf904, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "NeilLab :: leftradio");
    NGL_Font_DrawString(60, 22, 0xe79f, (NGL_Font*)&ms_shell_dlg_2_9_normal, Transparent, "v 1.5.2");
    NGL_Font_DrawString(12, 21, 0xe79f, (NGL_Font*)&ms_shell_dlg_2_12_normal, Transparent, "NT11");
    NGL_Font_DrawString(5, 253, 0xffff, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Lf:");
    NGL_Font_DrawString(5, 241, 0xffff, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Rf:");
    NGL_GP_DrawFillRect(5, 295, 475, 315, 0x106, DRAW, 0x106);
    NGL_Font_DrawString(5, 227, 0xffff, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Lf:");
    NGL_Font_DrawString(5, 215, 0xffff, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Rf:");
    NGL_Font_DrawString(5, 200, 0xffff, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Lf:");
    NGL_Font_DrawString(5, 188, 0xffff, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Rf:");
    NGL_Font_DrawString(5, 172, 0xffff, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Lf:");
    NGL_Font_DrawString(5, 160, 0xffff, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Rf:");
    NGL_GP_DrawLine(415, 279, 415, 54, 0xc000);
    NGL_GP_DrawLine(5, 44, 475, 44, 0xc000);
    NGL_Font_DrawString(415, 307, 0xf79f, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Channels");
    NGL_Font_DrawString(235, 307, 0xf79f, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Frequency");
    NGL_Font_DrawString(355, 307, 0xf79f, (NGL_Font*)&ms_shell_dlg_2_8_normal, Transparent, "Bits");
 
 
    /* Draw objects */
    NGL_GUI_DrawPageObjects();
}
 
/**
* @brief MainPage_Click
* Common click page objects
* @param None
* @retval None
*/
static void MainPage_Click(Coordinate data, NGL_TouchType type)
{
}
 
/**
* @brief btnControls_click
* Item/Items click event
* @param None
* @retval None
*/
static void btnControls_click(void)
{
}
 
/**
* @brief btnVisual_click
* Item/Items click event
* @param None
* @retval None
*/
static void btnVisual_click(void)
{
}
 
/**
* @brief btnSettings_click
* Item/Items click event
* @param None
* @retval None
*/
static void btnSettings_click(void)
{
}
 
/**
* @brief btnSourse_click
* Item/Items click event
* @param None
* @retval None
*/
static void btnSourse_click(void)
{
}
 
/**
* @brief nglSeekBar_2_click
* Item/Items click event
* @param None
* @retval None
*/
static void nglSeekBar_2_click(void)
{
}
 
/*********************************************************************************************************
END FILE
*********************************************************************************************************/

Как видно объявляется структура страницы с параметрами в полях, заготовки событий. в функции MainPage_Draw происходит отрисовка статичных элементов и "динамики" типа кнопки, прогрессбар и т.п. через вызов NGL_GUI_DrawPageObjects(), для того что бы это работало нужно сперва установить "активную" страницу вызвав NGL_GUI_SelectPage и передав в нее указатель на страницу, то есть отрисовка любой страницы должна иметь подобный вид:

/* Draw MainPage */
NGL_GUI_SelectPage(&MainPage);
NGL_GUI_GetSelectedPage()->Draw();

    На данный момент NGL поддерживает только тачскрин, далее мы эти воспользуемся в качестве примера использования событий. В остальных сгенерированных файлах находятся структуры шрифтов, изображений и т.п. Объявление типов этих структур можно посмотреть в NGL_types.h.

    Для проверки я буду использовать CoocoxIDE и МК STM32F407, а также 480х320 ЖК на контроллере R61581, МК и ЖК соеденены по FSMC 16 бит. Создадим пустой проект в Coocox IDE и добавляем все сгенерированные файлы в проект, также подключим библиотеку NGL.a и файлы NGL.h / NGL_types.h.

Компилируем и запускаем, если все сделано правильно то должны увидить следующее:

Основное место на flash занимают изображения и шрифты, сама по себе библиотека вполне компактна. Также размер увеличивает зависимость от стандартной библиотеки С, этот "недостаток" планировал исправить в следующем коммите NGL. Для примера с отрисовкой только "статических" "объектов" (линии, надписи и т.д.) и одного шрифта ms_shell_dlg_2_8 прошивка занимает: 

text data bss
9508 204 2140

            

Прошу извинить за качество фото :( , заливка всего экрана (очистка) и отрисовка интерфейса заняла 17149 мкс, или ~17 мс, весьма шустро, ~ 50 кадров/сек.

 

На сим пока все, спасибо всем за внимание, сожалею правда что так кратко. Продолжение следует...

 

 

 print( [ln.format() + '\n' for ln in links] )


 

 

Категория: ARM | Добавил: LeftRadio (05.09.2015)
Просмотров: 1895 | Комментарии: 1 | Теги: Embedded, PyQt5, Python3, Qt5, STM32, QtDesigner, NeilRLC, ngl_utils | Рейтинг: 0.0/0
Всего комментариев: 1
1 birg77out  
Здравствуйте. Использовал Windows XP Home 32 bits и Python 3.4.3. Не получается собрать SIP.
Эта команда вообще не работала
python configure.py –platform win32-g++
делал с такой
python configure.py -p win32-g++
Код
ia@dell MINGW32 ~
$ cd C:/Install/Python/sip-4.17/sip-4.17

ia@dell MINGW32 /c/Install/Python/sip-4.17/sip-4.17
$ python configure.py –platform win32-g++
Error: Unsupported macro name specified. Use the --show-build-macros flag to
see a list of supported macros.
This is SIP 4.17 for Python 3.4.3 on win32.

ia@dell MINGW32 /c/Install/Python/sip-4.17/sip-4.17
$ --show-build-macros flag
bash: --show-build-macros: command not found

ia@dell MINGW32 /c/Install/Python/sip-4.17/sip-4.17
$ python configure.py -p win32-g++
This is SIP 4.17 for Python 3.4.3 on win32.
The SIP code generator will be installed in C:\Python34.
The sip module will be installed in C:\Python34\Lib\site-packages.
The sip.h header file will be installed in C:\Python34\include.
The default directory to install .sip files in is C:\Python34\sip.
Creating siplib\sip.h...
Creating siplib\siplib.c...
Creating siplib\siplib.sbf...
Creating sipconfig.py...
Creating top level Makefile...
Creating sip code generator Makefile...
Creating sip module Makefile...

ia@dell MINGW32 /c/Install/Python/sip-4.17/sip-4.17
$ mingw32-make install
mingw32-make[1]: Entering directory 'C:/Install/Python/sip-4.17/sip-4.17/sipgen'
makefile:29: warning: overriding recipe for target '.c.o'
makefile:26: warning: ignoring old recipe for target '.c.o'
gcc -c -O2 -w -DNDEBUG -DUNICODE -DQT_LARGEFILE_SUPPORT -I. -o main.o main.c
main.c:20: stdio.h: No such file or directory
main.c:21: stdlib.h: No such file or directory
main.c:22: stdarg.h: No such file or directory
main.c:23: string.h: No such file or directory
main.c:24: ctype.h: No such file or directory
In file included from main.c:26:
sip.h:23: stdio.h: No such file or directory
sip.h:24: sys\types.h: No such file or directory
makefile:29: recipe for target 'main.o' failed
mingw32-make[1]: *** [main.o] Error 1
mingw32-make[1]: Leaving directory 'C:/Install/Python/sip-4.17/sip-4.17/sipgen'
makefile:7: recipe for target 'install' failed
mingw32-make: *** [install] Error 2

ia@dell MINGW32 /c/Install/Python/sip-4.17/sip-4.17
$

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]