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

GUI-SDL2 – GUI написанный на Haskell. Часть 3. Кнопки. Функциональное событийное программирование

Запись от Curry размещена 29.06.2018 в 16:19
Показов 3296 Комментарии 0

(Предыдущая тема)

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

Рассмотрим пример с основным типом кнопок в GUI-SDL2. Это виджет button.

Как обычно, в конце package.yaml, через пустую строку, допишем ещё одно приложение
Haskell
1
2
3
  3.Buttons:
    source-dirs:      3.Buttons
    main:             Main.hs
cоздадим каталог 3.Buttons в корневом каталоге проекта, и в нём новый файл Main.hs
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{-# LANGUAGE OverloadedStrings #-}
module Main where
 
import Control.Monad
import Data.Default
import qualified SDL
import GUI
import GUI.Skin.DefaultSkin
import GUI.Widget.Label
import GUI.Widget.Layout.LinearLayout
import SDL.Vect
import GUI.Widget.Button
 
main :: IO ()
main = runGUI defSkin  -- Запуск GUI с оформлением по умолчанию
 
        -- Список предзагруженных шрифтов : ключ, имя файла, размер шрифта, опции
        [GuiFontDef "label"       "PTN57F.ttf" 15 def -- label
        ] 
        def $ \gui -> do
    win <- newWindow gui "Buttons" SDL.defaultWindow{SDL.windowInitialSize  = V2 400 250}
    vL <- win $+ vLayout def
    lbStatus <- vL $+ label  def{ labelSize=V2 (-1) (-1)
                                , labelAlignment=AlignCenter
                                , labelText="Сюда будут выводится сообщения"}
    hL <- vL $+ hLayout def
    btn1 <- hL $+ button     def{ btnSize = V2 150 150
                                , btnPicture = ButtonLeftPicture "Messagebox_warning.png"
                                , btnTextWrapMode = TextWrap 0 Nothing
                                , btnText = "Сделать правую кнопку недоступной"
                                }
    btn2 <- hL $+ button     def{ btnSize = V2 100 150
                                , btnPicture = ButtonBottomPicture "Messagebox_lambda.png"
                                , btnTextWrapMode = TextWrap 0 Nothing
                                , btnText = "Сделать правую кнопку снова доступной"
                                }
    btn3 <- hL $+ button     def{ btnSize = V2 100 150
                                , btnPicture = ButtonBottomPicture "Messagebox_question.png"
                                , btnTextWrapMode = TextWrap 0 Nothing
                                , btnText = "Эту кнопку сделаем недоступной после нажатия левой"
                                }
 
    -- Реакции на события
 
    onClick btn1 $ do
        enableWidget btn3 False
        setText lbStatus "Перевели 3-ю кнопку в disable"
        
    onClick btn2 $ do
        enableWidget btn3 True
        setText lbStatus "Перевели 3-ю кнопку в enable"
        
    onClick btn3 $ 
        setText lbStatus "Просто нажали третью кнопку"
Заметили, что в этом примере задаётся параметр самого окна
Haskell
1
SDL.defaultWindow{SDL.windowInitialSize  = V2 400 250}
просто с целью сделать его подходящего размера. В прошлых примерах размер окна, может быть, был великоват для изготовления скриншотов.
Здесь используются функция defaultWindow и запись WindowConfig непосредственно из sdl2.

По размещению виджетов в окне, думаю, всё понятно из прошлых тем.

Виджет button может быть в трёх вариантах : без картинки , только с текстом - по умолчанию, в примере не используется; ButtonLeftPicture -- картинка слева, указывается имя графического файла; и ButtonBottomPicture - картинка под текстом.

Указываемые графические файлы вначале ищутся в каталоге ресурсов (GUI.Resources), в подкаталоге имя_скина.skin , если там не найдено, то просто в каталоге ресурсов. Кроме того, можно указать и абсолютный пусть к файлу. Это касается использования картинок и в других виджетах.

Новое здесь – это задание реакции на событие (onClick) и динамическое изменение свойств виджета (enableWidget, setText). Но и с этим, не должно быть сложностей у тех, кто вообще использовал когда-либо программирование на основе событий.

Выполним
Bash
1
stack build --exec 3.Buttons
Нажмите на изображение для увеличения
Название: buttons.PNG
Просмотров: 1434
Размер:	35.6 Кб
ID:	4902
Да, картинки для кнопок великоваты, но это только для демонстрации.

Проверьте: - цвет кнопок меняется при прохождении через них указателем мыши;
- если щёлкнуть по кнопке, то она принимает фокус, и тогда от неё можно переходить к следующей кнопке (или другому виджету способному принимать фокус) по Tab, к предыдущей по Shift-Tab. Действие кнопки в фокусе выполняется при нажатии Enter или пробел.

Можно сделать одну из кнопок в фокусе при открытии окна вписав в конце
Haskell
1
setFocus btn1
В GUI-SDL2 существуют и другие кнопки, описанные в модуле GUI.Widget.Button.

Виджет textureButton отображает переданную ему текстуру (может быть загруженную из файла, а может созданную на лету) на весь свой размер. Текстура может быть больше размера виджета, тогда колонки на которую текстура разбивается (если она в несколько раз шире виджета) используются для отображения состояния виджета (мышь над виджетом или нет, нажата кнопка мыши, состояние disabled), а номер ряда (если текстура в несколько раз выше виджета) переключается функцией setRowNum.

Виджет pictureButton - вариант предыдущей кнопки для которой текстура загружается из ресурса (из файла).

pictureWidget - упрощённый в настройке вариант кнопки, отображающий статическую картинку.
Впрочем, и на pictureWidget можно установить обработчик щелчка onClick и переключать ряд картинки по setRowNum.

Виджет buttonWithTriangle отображает кнопку на которой нарисована стрелка (треугольник) повёрнутая в указанную сторону с разным оформлением. В демонстрационном приложении из пакета GUI-SDL2 такие кнопки демонстрируются в EXAMPLE_NUM под номером 2.
Название: triangle_buttons.PNG
Просмотров: 1468

Размер: 465 байт

Продолжение следует.
Размещено в 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