Форум программистов, компьютерный форум, киберфорум
Curry
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

GUI-SDL2 – GUI написанный на Haskell. Часть 0. Введение. Первый helloworld

Запись от Curry размещена 21.06.2018 в 17:01
Показов 2981 Комментарии 0

Предпосылки к разработке GUI
Нормального, кроссплатформенного, графического интерфейса в настоящий момент для Haskell нет. Имеющиеся обёртки к сишным либам (GTK+, WxWidgets) оставляют желать лучшего, мягко говоря. С каждой новой версией и сишной библиотеки, и обёртки вылезают баги их совместимости. Особенно это заметно под Windows, т.к. под этой ОС авторы обёрток не привыкли их проверять.

Выбор
И так, я стал выбирать как можно более низкоуровневую кроссплатформенную библиотеку с тем, что бы она наименее мешалась, а практический весь GUI реализовать на Haskell поверх неё. Такой подход, как я предполагаю, максимально снизит «обёрточные» проблемы, или, если угодно, они будут сосредоточены в одном Haskell пакете (или нескольких взаимосвязанных) где фиксить их будет куда проще. Кроме того, разработка новых компонент GUI-я, так же будет происходить в рамках одного языка, что, очевидно, удобнее.
Из рассматриваемых кандидатов я отклонил OpenGL как очень избыточную для целей обычного (2D) интерфейса. К тому же она медленна под Windows.
От использования браузера через JavaScript я отказался на основании некоторых, накладываемых на такой интерфейс ограничений. Реализации такого типа графических интерфейсов на Haskell есть. И пусть. Но нужен и не браузерный вариант.

Выбор я остановил на библиотеке SDL2. И, хотя это мультимедийная библиотека, якобы заточенная под геймдев, мне в ней понравился простой API для работы с окнами, мышью и клавиатурой. Под винду она использует DirectX (хотя может и OpenGL), под другие ОС только OpenGL. Допускается создание любого числа окон операционной системы, получение сообщений от устройств ввода через очередь сообщений.
SDL2 умеет работать с весьма ограниченным набором примитивов и текстурами. Рендеринг текста и загрузка изображений из многих графических форматов реализована сопутствующими сишными библиотеками SDL_ttf и SDL2_image так же используемыми в GUI-SDL2.
Разрабатываемый пакет GUI-SDL2 готов в первом варианте, с относительно небольшим числом виджетов, диалогов. Далее я опишу как этим пользоваться на примерах.

Предварительно нужно установить свежий stack, а с помощью него ghc и msys2, сишные библиотеки и Haskell-обёртки к ним. Тут описывается как это сделать.
Сам пакет GUI-SDL2 доступен по адресу https://github.com/KolodeznyDiver/GUI-SDL2. Исходники прокомментированы на (плохом) русском языке.

Далее я предполагаю что, если вы хотите ознакомится с GUI-SDL, то вы его скачаете куда то на свой диск.
Bash
1
git clone https://github.com/KolodeznyDiver/GUI-SDL2
Так же, я предполагаю, что проект с учебными программами мы будем создавать во внешнем каталоге по отношению к каталогу с распакованным пакетом GUI-SDL2.

То есть, если GUI-SDL распаковали в каталог /foo/bar, и там теперь есть подкаталог GUI-SDL2, то учебный проект тоже будем создавать в /foo/bar, хотя создать учебный проект можно где угодно. Разница будет только в указании пути к каталогу GUI-SDL2 в stack.yaml.

Находясь во внешнем каталоге (/foo/bar) выполняем
Bash
1
stack new GUI-SDL2-tutorial simple-hpack
Примечание: я выбрал шаблон для нового проекта simple-hpack, а не просто simple, потому что мне нравится более новый формат файла конфигурации проекта package.yaml. Из него автоматически будет создаваться файл GUI-SDL2-tutorial.cabal. Кто предпочитает редактировать файл .cabal – используйте
Bash
1
stack new GUI-SDL2-tutorial simple
Сразу же, что бы не забыть, скопируем каталог GUI.Resources из GUI-SDL2 в GUI-SDL2-tutorial.
Переходим в созданный подкаталог GUI-SDL2-tutorial.
В stack.yaml , после строк
packages:
- .
Добавляем
- '../GUI-SDL2'
или другой абсолютный или относительный путь к директории пакета GUI-SDL2.

Для windows, после строки
# extra-deps: []
Вставьте
Haskell
1
2
3
extra-deps:
-   git: https://github.com/haskell-game/sdl2-image
    commit: 382395c763b473032721c71921b5c9241142178f
- пакет sdl2-image скачается с гитхаба автоматически. Можно скачать вручную и указать к нему путь в разделе «packages:».
stack.yaml целиком. На момент написания письма с lts-16.5
Haskell
1
2
3
4
5
6
7
8
9
resolver: lts-16.5
 
packages:
- .
- '../GUI-SDL2'
 
extra-deps:
-   git: https://github.com/haskell-game/sdl2-image
    commit: 382395c763b473032721c71921b5c9241142178f

В package.yaml потребуется больше изменений.
Во первых строка
category: Web
Мы не собираемся создавать программу относящуюся к web. И, хотя это ни на что не повлияет (пока мы не соберёмся выкладывать пакет на hackage.haskell.org), тем не менее, зададим более осмысленные категории
category: GUI SDL2
После
Haskell
1
2
dependencies:
  - base >= 4.7 && < 5
Добавим
Haskell
1
2
3
4
5
6
7
8
9
  - sdl2
  - GUI-SDL2
  - data-default
 
ghc-options:
  - -Wall
  - -Wname-shadowing
  - -fwarn-tabs
  - -Werror
Это означает что мы добавили пакеты которыми будем пользоваться и опции компилятора. Именно такие опции не обязательны, но я предпочитаю их. Расшифровка :
-Wall включает большинство предупреждений.
-Wname-shadowing – дополнительно включает предупреждение о затенении имени (в том числе и имени из подключенных модулей).
-fwarn-tabs – предупреждает об использовании символа табуляции. В исходниках на Haskell они противопоказаны.
-Werror – прекратить дальнейшую компиляцию если в модуле были предупреждения (так, как если бы это были ошибки).

Шаблон проекта предполагает что мы будем создавать одно приложение и его исходники будут находится в подкаталоге src. Я же предлагаю сделать один проект на много учебных приложений.
Опишем первое приложение в файле package.yaml .
После строки executables: удаляем всё, и, соблюдая отступы, добавляем
Haskell
1
2
3
  0.HelloWorld:
    source-dirs:      0.HelloWorld
    main:             Main.hs
Приложения–примеры я собираюсь нумеровать с 0.
package.yaml целиком
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
name:                GUI-SDL2-tutorial
version:             0.1.0.0
#synopsis:
#description:
homepage:            https://github.com/KolodeznyDiver/GUI-SDL2-tutorial#readme
license:             BSD3
author:              KolodeznyDiver
maintainer:          KldznDvr@gmail.com
copyright:           BSD3
category:            GUI SDL2
extra-source-files:
- README.md
 
dependencies:
  - base >= 4.7 && < 5
  - sdl2
  - GUI-SDL2
  - data-default
 
ghc-options:
  - -Wall
  - -Wname-shadowing
  - -fwarn-tabs
  - -Werror
  
  
executables:
  0.HelloWorld:
    source-dirs:      0.HelloWorld
    main:             Main.hs

Создаём подкаталог 0.HelloWorld в проекте,
А в нём файл Main.hs с минимальным содержанием позволяющим отобразить "Hello world" – в данном случае, в заголовке окна.
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
{-# LANGUAGE OverloadedStrings #-}
module Main where
 
import Control.Monad
import Data.Default
import qualified SDL
import GUI
import GUI.Skin.DefaultSkin
 
main :: IO ()
main = runGUI defSkin  -- Запуск GUI с оформлением по умолчанию
        [] def $ \gui -> void $ newWindow gui "Hello world" SDL.defaultWindow
Кстати, кодировка исходников на Haskell желательна utf-8 без BOM.

Осталось, находясь в каталоге проекта GUI-SDL2-tutorial, собрать и запустить новое приложение с именем 0.HelloWorld.

Примечание для пользователей win 7-8.1: С недавних пор ghc стал выводить в консоль цветные сообщения используя ANSI escape-последовательности. Под Windows нужно или отключить эту возможность ключом --color never, или использовать отдельно устанавливаемую программу терминала с поддержкой ANSI. hardentoo рекомендует https://conemu.github.io/ru/index.html. На win 10 escape-последовательности в консоли штатно поддерживаются.

И так, выполняем
Bash
1
stack build --exec 0.HelloWorld
Должно появиться окно с заголовком "Hello world".

Продолжение следует.
Размещено в GUI-SDL2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru