Lisp ã«ã¯é·ãè±ããªæŽå²ããããGUI éçºã«ãåãããšãèšããŸããå®éãæåã® GUI ãã«ããŒã¯ Lisp ã§æžãããŸããïŒãã㊠Apple ã«å£²åŽãããä»ã§ã¯ Interface Builder ã«ãªã£ãŠããŸãïŒã
Lisp ã¯å¯Ÿè©±çéçºèœåã§ãæåã§ãGUI ã¢ããªã±ãŒã·ã§ã³éçºã§ã¯ãã®å©ç¹ãããã«å€§ãããªããŸãã颿° 1 ã€ãã³ã³ãã€ã«ããã ãã§ GUI ãå³åº§ã«æŽæ°ãããæ§åãæ³åã§ããã§ããããã仿¥ã§ã¯å€ãã® GUI framework ã§ãããå¯èœã§ããã现éšã¯ããããç°ãªããŸãã
æåŸã«ããœãããŠã§ã¢éçºã§ã¯ãã©ããã«ãããŠã©ãå©çšè ãžå±ããããéèŠã§ããããã§ããäž»èŠãª 3 ã€ã® OS åãã«èªå·±å®çµå binary ãäœããå©çšè ãããã«ã¯ãªãã¯ã§å®è¡ã§ããããã«ã§ããŸãã
ããã§ã¯ãé©å㪠GUI framework ãéžã¶ããã®æ å ±ãæŽçããŠç€ºããŸããcontribute ããŠãããã«äŸã远å ããããå ã®ããã¥ã¡ã³ããè£ã£ããããã®ã¯æè¿ã§ãã
Introduction
ãã®ã¬ã·ãã§ã¯ã次㮠GUI toolkit ã玹ä»ããŸãã
- Tk ãš Ltk / nodgui
- Qt4 ãš Qtools
- IUP ãš lispnik/iup
- Gtk3 ãš cl-cffi-gtk
- Gtk4 ã® bindings ãæ¬²ããå Žå㯠cl-gtk4 ãèŠãŠãã ããããã㯠2022 幎 9 æã«å ¬éãããæ°ãã bindings ã§ãã
- Nuklear ãš Bodge-Nuklear
å ããŠã次ã®ãã®ãèŠãŠãããšããã§ãããã
- CAPI toolkitïŒCommon Application Programming InterfaceïŒ, ãã㯠LispWorks 補㮠proprietary 㪠toolkit ã§ããWindowsãGtk+ãCocoa ããŸããå®å šãª cross-platform toolkit ã§ãå©çšè ã®è©å€ãé«ãã§ããLispWorks ã«ã¯ iOS ãš Android ã® runtimes ããããŸããCAPI ã§äœãããäŸãšã㊠ScoreCloud ããããŸããLispWorks ã® free demo ã§è©ŠããŸãã
- Allegro CL ã® IDE ãš Common Graphics windowing systemïŒproprietaryïŒ: Allegro ã® IDE 㯠application éçºã®ããã®äžè¬ç㪠environment ã§ããCommon Graphics ãšãã windowing system ãšé£æºããŠåããŸãããã® IDE ã¯ãAllegro CL ã® Microsoft Windows çãLinux platformãFree BSDãMac çã§å©çšã§ããŸãã
- NEW! ð Allegro CL 10.1ïŒ2022 幎 3 æå ¬éïŒä»¥éãIDE ãš Common Graphics GUI toolkit 㯠browser äžã§åããŸããããã CG/JS ãšåŒã³ãŸãã
- CCL ã®çµã¿èŸŒã¿ Cocoa interface, Opusmodus ã®ãã㪠application ãäœãã®ã«äœ¿ãããŠããŸãã
- Clozure CL ã®çµã¿èŸŒã¿ Objective-C bridge ãš CocoaInterface ã¯ãCCL åãã® Cocoa interface ã§ããLisp code ã ãã§ Cocoa ã® user interface window ãåçã«äœããå
žåç㪠Xcode ã®æé ãé£ã°ããŸãã
- ãã® bridge 㯠ObjC ãšã©ãŒãæŸã£ãŠ Lisp ãšã©ãŒã«å€æããã®ãåŸæãªã®ã§ãmacOS GUI application ã§ã REPL ããŒã¹ã®å埩éçºãµã€ã¯ã«ãåããŸãã
- McCLIM ãš Garnet 㯠100% Common Lisp ã® toolkit ã§ããMcCLIM ã«ã¯ Broadway protocol ã§ browser äžã§åã ãããã¿ã€ã ããããGarnet ã«ã¯ Gtk ãžã®ç¶ç¶ç㪠interface ããããŸãã
- Alloy ã¯ããããæ°ããã® 100% Common Lisp toolkit ã§ãããšãã° Kandria ã²ãŒã ã§äœ¿ãããŠããŸãã
- eql, eql5, eql5-android ã¯ãECL ã«åã蟌ãŸããQt ã«ãåã蟌ãã Qt4/Qt5 Lisp ã§ããEQL5 ã® Android ç§»æ€çããããŸãã
- ABCL ãã Java Swing ã䜿ããã¢
- SBCL ã§ C ãã¡ã€ã«ãªãã« Gtk ã䜿ãäŸ ãš GTK-serverã
- Ceramic ã¯ãElectron ã§ cross-platform web app ãé
åžããããã®ãã®ã§ãã
- 詳ãã㯠Web Apps in Lisp ã® Electron ãš web view (webview, webui, CLOG Frame) ãèŠãŠãã ããã
- Barium toolkit
- äŸã® application: ChessLab (2025)
ãã®ã»ããawesome-cl#gui ãš Cliki ã«ãããã®ãåç §ããŠãã ããã
Tk (Ltk and nodgui)
TkïŒããã㯠Tcl/TkãTcl ã programming language ã§ãïŒã¯ãå€èãèŠãç®ã ãšããæªè©ããããŸããã§ãããããã¯ä»ã§ã¯ïŒããã»ã©ïŒåœãŠã¯ãŸããŸããã1997 幎㮠version 8 以éã¯ç¹ã«ããã§ãããã¶ããæã£ãŠããããè¯ããã®ã§ãã
ãã㯠nodgui ã®çµã¿èŸŒã¿ theme ã䜿ã£ãã·ã³ãã«ãª GUI ã§ãïŒè©³çްã¯åŸè¿°ïŒã

åã theme ã® treeview ã§ãã

Arc theme ã䜿ã£ããtree listãcheckboxãbuttonãlabel ã衚瀺ããããã¡ãã® media player ã§ãã

MacOS theme ã® demo ã§ãã

ãããã«å ããŠãttkthemes ã Forest theme ãªã©å€æ°ã® theme ã䜿ããŸãããã® tcl/tk ã®äžèЧ ãèŠãŠãã ããã
ã§ã¯ Tk ã¯äœã«åããŠããã®ã§ãããããTk ã® widget ã®çš®é¡ã¯è±å¯ã§ã¯ãããŸãããã䟿å©ãª canvas ããããããã«ããã€ãç¬èªã®ç¹åŸŽããããŸããGUI ã å®å šã«å¯Ÿè©±çã« éçºã§ããcore app ãã GUI ã é éå®è¡ ã§ããŸããããã cross-platform ã§ãã
ã€ãŸã Tk 㯠native ã§ã¯ãªããæå ç«¯ã®æ©èœãåããŠããããã§ããããŸããããå®çžŸã®ãã GUI toolkitïŒå Œ programming languageïŒã§ãä»ãæ¥çã§äœ¿ãããŠããŸããåçŽãª GUI ãçŽ æ©ãäœããããšããé åžã®ãããããéèŠããããšããå®å®æ§ãå¿ èŠãªãšãã«åããŠããŸãã
Lisp bindings 㯠2 ã€ãããŸããLtk ãš nodgui ã§ããNodguiïŒâNo Drama GUIâïŒã¯ Ltk ã® fork ã§ã远å widgetïŒããšãã° auto-completion list widgetïŒãéåæ event loopããããŠäœããã©ã€ãã©ãªã«ä»å±ããæå€ãšèŠæ ãã®è¯ã âYaruâ theme ãåããŠããŸããã»ãã® theme ãå ¥ããŠäœ¿ãã®ãç°¡åã§ãã詳现ã¯åŸè¿°ããŸãã
- Tk is Written in: Tcl
-
Portability: cross-platform (Windows, macOS, Linux).
-
Widgets: Tk 㯠widget ã®è±å¯ãã売ãã§ã¯ãããŸãããæ¢å® widget ã¯ å°æ° ã§ãdate picker ã®ãããªéèŠãªãã®ãæ¬ ããŠããŸããæ¡åŒµïŒNodgui ãªã©ïŒã§è£ããŸãããããŸã native ã«ã¯èŠããŸãããcalendar 㯠Tk extension ãæäŸããŠããããã¡ãã®ã»ããèŠæ ããããã§ãã
-
Interactive development: éåžžã«åããŠããŸãã
-
Graphical builder: ãªã
- Other features:
- remote execution: Lisp ãš Tcl/Tk ã®æ¥ç¶ã¯ stream çµç±ã§è¡ãããŸãããã®ãããLisp program ã 1 å°ã® computer ã§åãããGUI ãå¥ã® computer ã«è¡šç€ºã§ããŸããclient åŽã«å¿ èŠãªã®ã¯ tcl/tk ã®ã€ã³ã¹ããŒã«ãš remote.tcl script ã ãã§ããLtk-remote ãèŠãŠãã ããã
- Bindings documentation: çãã§ããååã§ããNodgui ãåæ§ã§ãã
- Bindings stability: ãšãŠãå®å®ããŠããŸãã
- Bindings activity: Ltk ã¯äœãïŒäž»ã« maintenanceïŒãNodgui ã¯æŽ»çºïŒæ°æ©èœããïŒã§ãã
- Licence: Tcl/Tk 㯠BSD 颚ãLtk 㯠LGPL ã§ãã
- äŸ:
- Fulci - movie collection ãæŽçãã program ã§ãã
- Ltk small games - snake ãš tic-tac-toe ã§ãã
- cl-pkr - cross-platform ã® color picker ã§ãã
- cl-torrents - äººæ° tracker ã® torrent ãæ€çŽ¢ããŸããCLIãreadlineãã·ã³ãã«ãª Tk GUI ãåããŠããŸãã
- 远å ã®äŸ:
- https://peterlane.netlify.app/ltk-examples/: tkdocs tutorial åãã® LTk äŸã§ãã
- LTk Plotchart - tklib/plotchart library ã LTk ã§äœ¿ãããã® wrapper ã§ããxy plotãgantt chartã3d bar chart ãªã© 20 çš®é¡ä»¥äžã® chart ãå«ã¿ãŸãã
widget äžèЧ
(ç¶²çŸ çãªäžèЧã§ã¯ãããŸãã)
Button Canvas Check-button Entry Frame Label Labelframe Listbox
Menu Menubutton Message
Paned-window
Radio-button Scale
Scrollbar Spinbox Text
Toplevel Widget Canvas
Ltk-megawidgets:
progress
history-entry
menu-entry
nodgui ã«è¿œå ããããã®:
treelist tooltip searchable-listbox date-picker calendar autocomplete-listbox
password-entry progress-bar-star notify-window
dot-plot bar-chart equalizer-bar
swap-list
Qt4 (Qtools)
Qt ãš Qt4 ãæ¹ããŠç޹ä»ããå¿ èŠãããã§ãããããQt ã¯éåžžã«å€§ãããäœã§ãå ¥ã£ãŠããŸããUI widget ã ãã§ãªããnetworking ã D-BUS ãªã©å€ãã®å±€ãæäŸããŸãã
Qt 㯠open-source software ãªãç¡æã§äœ¿ããŸãããproprietary software ãé åžããå Žåã¯æ¡ä»¶ã確èªããŠãã ããã
Qtools bindings 㯠Qt4 ã察象ã«ããŠããŸããQt5 ã® Lisp bindings 㯠https://github.com/commonqt/commonqt5/ ã§ããŸã æ¬çªåãã§ã¯ãããŸããã
Qtools ã® companion library ãšããŠãæåã® Qtools application ãäœã£ãããã²èŠãŠããããã®ã Qtools-ui ã§ãã䟿å©ãª widget ãšæ¢æ component ã®éãŸãã§ãçã ãã¢åç» ããããŸãã
- Framework written in: C++
- Framework Portability: multi-platform, Android, embedded systems, WASM.
-
Bindings Portability: Qtools 㯠WindowsãmacOSãGNU/Linux ã® x86 desktop platform ã§åããŸãã
-
Widgets choice: è±å¯ã
-
Graphical builder: ããã
-
Other features: web browser ãªã©å€æ°ã
- Bindings documentation: 詳ãã説æãšå°æ°ã®äŸããããŸããQt ã®äºåç¥èãå¿ èŠã§ãã
- Bindings stability: å®å®ã
- Bindings activity: 掻çºã
- Qt Licence: åçšãš open source ã®äž¡æ¹ããããŸãã
- äŸ:
- https://github.com/Shinmera/qtools/tree/master/examples
- https://github.com/Shirakumo/lionchat
- https://github.com/shinmera/halftone - ã·ã³ãã«ãª image viewer
Gtk+3 (cl-cffi-gtk)
Gtk+3 㯠GNOME application ãäœãäž»èŠ library ã§ããLisp bindings ãšããŠã¯ãçŸæç¹ã§æãé²ãã§ãããã®ã cl-cffi-gtk ã§ãã䞻㫠GNU/Linux åãã«äœãããŸããããGtk 㯠macOS ã§ãåé¡ãªãåããä»ã§ã¯ Windows ã§ã䜿ããŸãã
- Framework written in: C
-
Portability: GNU/Linux ãš macOSãWindows ã§ãå¯ã
-
Widgets choice: è±å¯ã
- Graphical builder: ãã: Gladeã
-
Other features: web browser (WebKitGTK)
- Bindings documentation: ãšãŠãè¯ãã§ã: http://www.crategus.com/books/cl-gtk/gtk-tutorial.html
- Bindings stability: å®å®ã
- Bindings activity: 掻åéã¯å°ãªãã§ãããéçºã¯ç¶ããŠããŸãã
- Licence: LGPL
- äŸ:
- Glade ã§äœããã Atmosphere Calculatorã
- 远å ã® documentation ãšäŸ:
IUP (lispnik/IUP)
IUP ã¯ããã©ãžã«ã®ãªãªããžã£ãã€ãã»ã«ããªãã¯å€§åŠã§æŽ»çºã«éçºãããŠãã cross-platform GUI toolkit ã§ããnative control ã䜿ããWindows ã§ã¯ Windows APIãGNU/Linux ã§ã¯ Gtk3 ã䜿ããŸããå·çæç¹ã§ã¯ Cocoa çãéçºäžã§ãiOSãAndroidãWASM çããããŸããIUP ã®ç¹åŸŽã¯ API ãå°ãã ããšã§ãã
[Lisp bindings] 㯠lispnik/iup ã§ããC source ããèªåçæãããŠãããããããã§ããŠããŸããæ°ãã IUP version ã«è¿œåŸããæéãå°ãªããå¿ èŠãªæé ãææžåãããŠããŸããããã«ãã bus factor ã®é¢ã§ãå®å¿ã§ãã
IUP 㯠Tk ãš Gtk/Qt ã®äžéã«ãããéåžžã«è¯ãéžæè¢ã§ãã
- Framework written in: CïŒå ¬åŒ API 㯠Lua ãš LED ã«ããããŸãïŒ
-
Portability: Windows ãš LinuxãCocoaãiOSãAndroidãWASM çãäœæ¥äžã§ãã
-
Widgets choice: äžçšåºŠãweb browser window ãå«ã¿ãŸãïŒLinux ã§ã¯ WebkitGTKãWindows ã§ã¯ IE ã® WebBrowserïŒã
-
Graphical builder: ãã: IupVisualLED
-
Other features: OpenGLãweb browserïŒGNU/Linux ã§ã¯ WebKitGTKïŒãplottingãScintilla text editor
- Bindings documentation: äŸãš README ã¯è¯ãã§ããããã以å€ã¯å°ãªãã§ãã
- Bindings stability: alphaïŒãã ãå®å šã«çæãããŠããŠãåé¡ãªãåããŸãïŒã
- Bindings activity: å°ãªãã§ããå®å®ããŠããŠãæ°ãã IUP version ã«ãåå¿ããŸãã
- Licence: IUP ã bindings ã MIT license ã§ãã
List of widgets
Radio, Tabs, FlatTabs, ScrollBox, DetachBox,
Button, FlatButton, DropButton, Calendar, Canvas, Colorbar, ColorBrowser, DatePick, Dial, Gauge, Label, FlatLabel,
FlatSeparator, Link, List, FlatList, ProgressBar, Spin, Text, Toggle, Tree, Val,
listDialog, Alarm, Color, Message, Font, Scintilla, file-dialogâŠ
Cells, Matrix, MatrixEx, MatrixList,
GLCanvas, Plot, MglPlot, OleControl, WebBrowser (WebKit/Gtk+)âŠ
drag-and-drop
WebBrowser

Nuklear (Bodge-Nuklear)
Nuklear ã¯å°ã㪠immediate-mode GUI toolkit ã§ãã
Nuklear is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.
Lisp bindings 㯠Bodge-Nuklear ã§ãäžäœã® companion ãšã㊠bodge-ui ãš bodge-ui-window ããããŸãã
åŸæ¥ã® UI framework ãšéããNuklear ã§ã¯æç»ã«ãŒãã input 管çãéçºè ãåŒãç¶ããŸããèšå®ã¯å°ãå¢ããŸãããã²ãŒã ããæ°ãã control ãäœããã application ã«ã¯ç¹ã«åããŠããŸãã
- Framework written in: ANSI Cãsingle-header libraryã
-
Portability: C ãåããšãããªãã©ãã§ããNuklear ã«ã¯ platform-specific code ã¯å«ãŸããŠããŸãããOS ã window ã®çŽæ¥åŠçã Nuklear ã§ã¯è¡ãããŸããããã®ä»£ããããã¹ãŠã® input state ã platform-specific code ãæäŸããå¿ èŠããããŸãã
-
Widgets choice: å°ãªãã
-
Graphical builder: ãªãã
-
Other features: skin ãš customization ãå®å šã«å¯èœã
- Bindings stability: å®å®ã
- Bindings activity: 掻çºã
- Licence: MIT ã Public DomainïŒunlicenseïŒã
- Example applications:
- Trivial-gamekit
- Obvius - a resurrected image processing library.
- Notalone - an autumn 2017 Lisp Game Jam entry.
List of widgets
æç²ã§ãã
buttons, progressbar, image selector, (collapsable) tree, list, grid, range, slider, color picker,
date-picker

Getting started
Tk
Ltk is quick and easy to grasp.
(ql:quickload "ltk")
(in-package :ltk-user)
How to create widgets
All widgets are created with a regular make-instance and the widget name:
(make-instance 'button)
(make-instance 'treeview)
This makes Ltk explorable with the default symbol completion.
How to start the main loop
As with most bindings, the GUI-related code must be started inside a macro that
handles the main loop, here with-ltk:
(with-ltk ()
(let ((frame (make-instance 'frame)))
âŠ))
How to display widgets
widget ãäœã£ãããlayout ã«é
眮ããå¿
èŠããããŸããTk ã«ã¯ããã€ãé
çœ®æ¹æ³ããããŸãããä»äœ¿ãã¹ããªã®ã¯ grid ã§ããgrid 㯠widgetãåãè¡ãããã€ãã® optional parameter ãåŒæ°ã«åã颿°ã§ãã
éåžžã® Lisp code ãšåããã颿°ã® signature 㯠editor ã«åºãŸããããã Ltk ããã©ããããããŠãããŸãã
button ã衚瀺ããäŸã§ãã
(with-ltk ()
(let ((button (make-instance 'button :text "hello")))
(grid button 0 0)))
ããããšã¯ããã ãã§ãã
event ã«åå¿ãã
å€ãã® widget ã«ã¯ :command argument ããããwidget ã® event ãçºçãããšãã«å®è¡ããã lambda ãåãåããŸããbutton ã®å Žåã¯ã¯ãªãã¯æã§ãã
(make-instance 'button
:text "Hello"
:command (lambda ()
(format t "clicked")))
察話çéçº
(start-wish) ã§ Tk process ã background ã§èµ·åãããšãwidget ãäœã£ãŠ grid ã«çœ®ãäœæ¥ã察話çã«è¡ããŸãã
詳ãã㯠ããã¥ã¡ã³ã ãèŠãŠãã ããã
çµãã£ãã (exit-wish) ãåŒã³ãŸãã
Nodgui
Nodgui ã® demo ã詊ãã«ã¯æ¬¡ã®ããã«ããŸãã
(ql:quickload "nodgui")
(nodgui.demo:demo)
èŠãç®ã®ãã theme ã§ demo ãèªã¿èŸŒããªããæ¬¡ã®ããã«ããŸãã
(nodgui.demo:demo :theme "yaru")
or
(setf nodgui:*default-theme* "yaru")
(nodgui.demo:demo)
Nodgui UI theme
nodgui ã«ä»å±ãã âyaruâ theme ã䜿ãã«ã¯ãåçŽã«æ¬¡ã®ããã«ããŸãã
(with-nodgui ()
(use-theme "yaru")
âŠ)
or
(with-nodgui (:theme "yaru")
âŠ)
or
(setf nodgui:*default-theme* "yaru")
(with-nodgui ()
âŠ)
å¥ã® tcl theme ãã€ã³ã¹ããŒã«ããŠèªã¿èŸŒãããšãã§ããŸããããšãã° Forest ttk theme ã ttkthemes ã clone ããŸããproject directory ã¯æ¬¡ã®ããã«ãªããŸãã
yourgui.asd
yourgui.lisp
ttkthemes/
ttkthemes/ ã®äžã§ã¯ png/ directory ã« theme ãããããã以å€ã¯çŸæç¹ã§æªå¯Ÿå¿ã§ãã
/ttkthemes/ttkthemes/png/arc/arc.tcl
nodgui ã§ .tcl file ãèªã¿èŸŒã¿ããã® theme ã䜿ãããæç€ºããŸãã
(with-nodgui ()
(eval-tcl-file "/ttkthemes/ttkthemes/png/arc/arc.tcl")
(use-theme "arc")
⊠code here âŠ)
ããã§çµããã§ããapplication ã¯æ°ãããããããèŠæ ãã®ãã GUI theme ã䜿ãããã«ãªããŸãã
Qt4
(ql:quickload '(:qtools :qtcore :qtgui))
(defpackage #:qtools-test
(:use #:cl+qt)
(:export #:main))
(in-package :qtools-test)
(in-readtable :qtools)
æ®ããå ¥ãã main widget ãäœããŸãã
(define-widget main-window (QWidget)
())
ãã® main widget ã®äžã« input field ãš button ãäœããŸãã
(define-subwidget (main-window name) (q+:make-qlineedit main-window)
(setf (q+:placeholder-text name) "Your name please."))
(define-subwidget (main-window go-button) (q+:make-qpushbutton "Go!" main-window))
暪ã«äžŠã¹ãŸãã
(define-subwidget (main-window layout) (q+:make-qhboxlayout main-window)
(q+:add-widget layout name)
(q+:add-widget layout go-button))
ãããŠè¡šç€ºããŸãã
(with-main-window
(window 'main-window))

ããã§åœ¢ã¯ã§ããŸãããããŸã click event ã«ã¯åå¿ããŠããŸããã
event ã«åå¿ãã
Qt ã§ event ã«åå¿ããã«ã¯ signal ãš slot ã䜿ããŸããslot 㯠signal ãåãåããããã㯠signal ã« âæ¥ç¶ããâ 颿°ã§ãsignal 㯠event ã®éã³æã§ãã
widget ã¯ãã§ã«èªåã® signal ãéã£ãŠããŸããããšãã° button 㯠âpressedâ event ãéããŸãããã®ããããããŠãã¯ããã«æ¥ç¶ããã ãã§æžã¿ãŸãã
ãã ããå¿ èŠãªãç¬èªã® signal 矀ãäœãããšãã§ããŸãã
çµã¿èŸŒã¿ event
go-button ã pressed ãš return-pressed event ã«æ¥ç¶ããmessage box ã衚瀺ããŸãã
- ããã
define-slot颿°ã®äžã§è¡ãã - ãã®äžã§ event ãžã®æ¥ç¶ã確ç«ãã
- ããã« message box ãäœããŸãã
nameinput field ã® text ã¯(q+:text name)ã§ååŸããŸãã
(define-slot (main-window go-button) ()
(declare (connected go-button (pressed)))
(declare (connected name (return-pressed)))
(q+:qmessagebox-information main-window
"Greetings" ;; title
(format NIL "Good day to you, ~a!" (q+:text name))))
ããã§å®æã§ããæ¬¡ã®ããã«å®è¡ããŸãã
(with-main-window (window 'main-window))
ç¬èª event
äžãšåãæ©èœãå®è£
ããŸããã説æã®ããã« button ã¯ãªãã¯æã«çºç«ãã name-set ãšããç¬èª signal ãäœããŸãã
ãŸã signal ãå®çŸ©ããŸãããã㯠main-window ã®äžã§è¡ããå㯠string ã§ãã
(define-signal (main-window name-set) (string))
æåã® slot ãäœã£ãŠ button ã pressed ãš return-pressed event ã«åå¿ãããŸãããã ãããã§ã¯äžã®ããã« message box ãäœãã®ã§ã¯ãªããinput field ã®å€ãèŒãã name-set signal ãéããŸãã
(define-slot (main-window go-button) ()
(declare (connected go-button (pressed)))
(declare (connected name (return-pressed)))
(signal! main-window (name-set string) (q+:text name)))
So far, nobody reacts to name-set. We create a second slot that
connects to it, and displays our message. Here again, we precise the
parameter type.
(define-slot (main-window name-set) ((new-name string))
(declare (connected main-window (name-set string)))
(q+:qmessagebox-information main-window "Greetings"
(format NIL "Good day to you, ~a!" new-name)))
ãããŠå®è¡ããŸãã
(with-main-window (window 'main-window))
Building and deployment
It is possible to build a binary and bundle it together with all the necessary shared libraries.
Please read https://github.com/Shinmera/qtools#deployment.
You might also like this Travis CI script to build a self-contained binary for the three OSes.
Gtk3
The documentation is exceptionally good, including for beginners.
The library to quickload is cl-cffi-gtk. It is made of numerous
ones, that we have to :use for our package.
(ql:quickload "cl-cffi-gtk")
(defpackage :gtk-tutorial
(:use :gtk :gdk :gdk-pixbuf :gobject
:glib :gio :pango :cairo :common-lisp))
(in-package :gtk-tutorial)
How to run the main loop
As with the other libraries, everything happens inside the main loop
wrapper, here with-main-loop.
How to create a window
(make-instance 'gtk-window :type :toplevel :title "hello" ...).
How to create a widget
All widgets have a corresponding class. We can create them with
make-instance 'widget-class, but we preferably use the constructors.
The constructors end with (or contain) ânewâ:
(gtk-label-new)
(gtk-button-new-with-label "Label")
How to create a layout
(let ((box (make-instance 'gtk-box :orientation :horizontal
:spacing 6))) ...)
then pack a widget onto the box:
(gtk-box-pack-start box mybutton-1)
and add the box to the window:
(gtk-container-add window box)
and display them all:
(gtk-widget-show-all window)
Reacting to events
Use g-signal-connect + the concerned widget + the event name (as a
string) + a lambda, that takes the widget as argument:
(g-signal-connect window "destroy"
(lambda (widget)
(declare (ignore widget))
(leave-gtk-main)))
Or again:
(g-signal-connect button "clicked"
(lambda (widget)
(declare (ignore widget))
(format t "Button was pressed.~%")))
Full example
(defun hello-world ()
;; in the docs, this is example-upgraded-hello-world-2.
(within-main-loop
(let ((window (make-instance 'gtk-window
:type :toplevel
:title "Hello Buttons"
:default-width 250
:default-height 75
:border-width 12))
(box (make-instance 'gtk-box
:orientation :horizontal
:spacing 6)))
(g-signal-connect window "destroy"
(lambda (widget)
(declare (ignore widget))
(leave-gtk-main)))
(let ((button (gtk-button-new-with-label "Button 1")))
(g-signal-connect button "clicked"
(lambda (widget)
(declare (ignore widget))
(format t "Button 1 was pressed.~%")))
(gtk-box-pack-start box button))
(let ((button (gtk-button-new-with-label "Button 2")))
(g-signal-connect button "clicked"
(lambda (widget)
(declare (ignore widget))
(format t "Button 2 was pressed.~%")))
(gtk-box-pack-start box button))
(gtk-container-add window box)
(gtk-widget-show-all window))))

IUP
Please check the installation instructions upstream. You may need one system dependency on GNU/Linux, and to modify an environment variable on Windows.
Finally, do:
(ql:quickload "iup")
We are not going to :use IUP (it is a bad practice generally after all).
(defpackage :test-iup
(:use :cl))
(in-package :test-iup)
The following snippet creates a dialog frame to display a text label.
(defun hello ()
(iup:with-iup ()
(let* ((label (iup:label
:title
(format nil "Hello, World!~%IUP ~A~%~A ~A"
(iup:version)
(lisp-implementation-type)
(lisp-implementation-version))))
(dialog (iup:dialog label :title "Hello, World!")))
(iup:show dialog)
(iup:main-loop))))
(hello)
SBCL ã«ã€ããŠã®éèŠãªæ³šæã§ããçŸæç¹ã§ã¯ãŒãé€ç®ãšã©ãŒãææããå¿ èŠããããŸãïŒãã® issue ã®é²å±ãèŠãŠãã ããïŒããã®ãããã¹ããããã¯æ¬¡ã®ããã«å®è¡ããŸãã
(defun run-gui-function ()
#-sbcl (gui-function)
#+sbcl
(sb-int:with-float-traps-masked
(:divide-by-zero :invalid)
(gui-function)))
ã¡ã€ã³ã«ãŒãã®èµ·åæ¹æ³
ãããŸã§èŠãŠãã bindings ãšåæ§ã«ãwidget 㯠with-iup macro ã®äžã§è¡šç€ºããiup:main-loop ãåŒã³ãŸãã
widget ã®äœãæ¹
constructor 颿°ã¯ widget åãã®ãã®ã§ããiup:labelãiup:dialog ãªã©ã§ãã
widget ã®è¡šç€ºæ¹æ³
å¿
ã âshowâ ããŠãã ããã(iup:show dialog) ã§ãã
widget 㯠frame ã«ãŸãšãããã瞊 (vbox) ãæšª (hbox) ã«äžŠã¹ãããŸãïŒäžã®äŸãåç
§ïŒã
window ã®ãªãµã€ãºæã« widget ã䌞瞮ããããå Žå㯠:expand :yes ã䜿ããŸãïŒãŸã㯠:horizontalã:verticalïŒã
:alignement property ã䜿ããŸãã
widget ã® attribute ã®ååŸãšèšå®
attribute ã®å€ãåŸãã«ã¯ (iup:attribute widget attribute) ã䜿ããèšå®ãããšãã¯ããã« setf ããŸãã
event ã«åå¿ãã
ã»ãšãã©ã® widget 㯠:action parameter ãåãã1 ã€ã® parameterïŒhandleïŒãæã€ lambda ãåãåããŸãã
(iup:button :title "Test &1"
:expand :yes
:tip "Callback inline at control creation"
:action (lambda (handle)
(iup:message "title" "button1's action callback")
iup:+default+))
以äžã§ã¯ label ãäœãããã®äžã« button ã眮ããŸããbutton ãã¯ãªãã¯ãããš message dialog ã衚瀺ããŸãã
(defun click-button ()
(iup:with-iup ()
(let* ((label (iup:label :title
(format nil "Hello, World!~%IUP ~A~%~A ~A"
(iup:version)
(lisp-implementation-type)
(lisp-implementation-version))))
(button (iup:button :title "Click me"
:expand :yes
:tip "yes, click me"
:action
(lambda (handle)
(declare (ignorable handle))
(iup:message "title"
"button clicked")
iup:+default+)))
(vbox
(iup:vbox (list label button)
:gap "10"
:margin "10x10"
:alignment :acenter))
(dialog (iup:dialog vbox :title "Hello, World!")))
(iup:show dialog)
(iup:main-loop))))
#+sbcl
(sb-int:with-float-traps-masked
(:divide-by-zero :invalid)
(click-button))
ã¯ãªãã¯åæ°ã® counter ãäœã䌌ãäŸã瀺ããŸããlabel ãšãã® title ã«åæ°ãä¿æããŸããtitle ã¯æŽæ°ã§ãã
(defun counter ()
(iup:with-iup ()
(let* ((counter (iup:label :title 0))
(label (iup:label :title
(format nil "The button was clicked ~a time(s)."
(iup:attribute counter :title))))
(button (iup:button :title "Click me"
:expand :yes
:tip "yes, click me"
:action (lambda (handle)
(declare (ignorable handle))
(setf (iup:attribute counter :title)
(1+ (iup:attribute counter :title 'number)))
(setf (iup:attribute label :title)
(format nil "The button was clicked ~a times."
(iup:attribute counter :title)))
iup:+default+)))
(vbox
(iup:vbox (list label button)
:gap "10"
:margin "10x10"
:alignment :acenter))
(dialog (iup:dialog vbox :title "Counter")))
(iup:show dialog)
(iup:main-loop))))
(defun run-counter ()
#-sbcl
(counter)
#+sbcl
(sb-int:with-float-traps-masked
(:divide-by-zero :invalid)
(counter)))
list widget ã®äŸ
以äžã§ã¯ãåäžéžæãšè€æ°éžæã® list widget ã 3 ã€äœããæ¢å®å€ïŒäºåéžæè¡ïŒãèšå®ããŠã暪ã«äžŠã¹ãŸãã
(defun list-test ()
(iup:with-iup ()
(let* ((list-1 (iup:list :tip "List 1" ;; tooltip
;; multiple selection
:multiple :yes
:expand :yes))
(list-2 (iup:list :value 2 ;; default index of the selected row
:tip "List 2" :expand :yes))
(list-3 (iup:list :value 9 :tip "List 3" :expand :yes))
(frame (iup:frame
(iup:hbox
(progn
;; populate the lists: display integers.
(loop for i from 1 upto 10
do (setf (iup:attribute list-1 i)
(format nil "~A" i))
do (setf (iup:attribute list-2 i)
(format nil "~A" (+ i 10)))
do (setf (iup:attribute list-3 i)
(format nil "~A" (+ i 50))))
;; hbox wants a list of widgets.
(list list-1 list-2 list-3)))
:title "IUP List"))
(dialog (iup:dialog frame :menu "menu" :title "List example")))
(iup:map dialog)
(iup:show dialog)
(iup:main-loop))))
(defun run-list-test ()
#-sbcl (hello)
#+sbcl
(sb-int:with-float-traps-masked
(:divide-by-zero :invalid)
(list-test)))
Nuklear
泚æ: å·çæç¹ã§èè ã®èšèã«ããã°ãbodge-ui ã¯ãŸã éçºåææ®µéã§ãäžè¬å©çšã«ã¯æªå¯Ÿå¿ã§ããä¿®æ£ãå¿ èŠãªçãããã€ããããAPI ã«å€æŽãå ¥ãå¯èœæ§ããããŸãã
bodge-ui 㯠Quicklisp æ¬äœã§ã¯ãªããç¬èªã® Quicklisp distribution ã«ãããŸãããŸããããã€ã³ã¹ããŒã«ããŸãã
(ql-dist:install-dist "http://bodge.borodust.org/dist/org.borodust.bodge.txt" :replace t :prompt nil)
OpenGL 2 renderer ãæå¹ã«ãããå Žåã ãããã®è¡ã®ã³ã¡ã³ããå€ããŠè©äŸ¡ããŸãã
;; (cl:pushnew :bodge-gl2 cl:*features*)
bodge-ui-window ã quickload ããŸãã
(ql:quickload "bodge-ui-window")
çµã¿èŸŒã¿ example ãå®è¡ã§ããŸãã
(ql:quickload "bodge-ui-window/examples")
(bodge-ui-window.example.basic:run)
ã§ã¯ãç°¡å㪠application ãæžãããã® package ãå®çŸ©ããŸãã
(cl:defpackage :bodge-ui-window-test
(:use :cl :bodge-ui :bodge-host))
(in-package :bodge-ui-window-test)
(defpanel (main-panel
(:title "Bodge UI ãžãããã")
(:origin 200 50)
(:width 400) (:height 400)
(:options :movable :resizable
:minimizable :scrollable
:closable))
(label :text "å
¥ãåã® widget:")
(horizontal-layout
(radio-group
(radio :label "éžæè¢ 1")
(radio :label "éžæè¢ 2" :activated t))
(vertical-layout
(check-box :label "ãã§ã㯠1" :width 100)
(check-box :label "ãã§ã㯠2"))
(vertical-layout
(label :text "å·Šå¯ã" :align :left)
(label :text "äžå€®" :align :centered)
(label :text "å³å¯ã" :align :right)))
(label :text "å¹
ã«å¿ããŠäŒžçž®:")
(horizontal-layout
(button :label "å¯å€")
(button :label "æå°å¹
" :width 80)
(button :label "åºå®å¹
" :expandable nil :width 100))
(label :text "å¹
ã«å¿ããŠäŒžçž®:")
(horizontal-layout
(button :label "1.0" :expand-ratio 1.0)
(button :label "0.75" :expand-ratio 0.75)
(button :label "0.5" :expand-ratio 0.5))
(label :text "æ®ã:")
(button :label "æäžäœãã¿ã³"))
(defparameter *window-width* 800)
(defparameter *window-height* 600)
(defclass main-window (bodge-ui-window:ui-window) ()
(:default-initargs
:title "Bodge UI Window ã®äŸ"
:width *window-width*
:height *window-height*
:panels '(main-panel)
:floating t
:opengl-version #+bodge-gl2 '(2 1)
#+bodge-gl2 '(3 3)))
(defun run ()
(bodge-host:open-window (make-instance 'main-window)))
and run it:
(run)

event ã«åå¿ããã«ã¯ã次㮠signal ã䜿ããŸãã
:on-click
:on-hover
:on-leave
:on-change
:on-mouse-press
:on-mouse-release
ãããã¯åŒæ° 1 ã€ãã€ãŸã panel ãåã颿°ãåãåããŸãããã ãæ³šæããŠãã ãããwidget ããã® state ã«ããããã ã¯æç» cycle ããšã«åŒã°ãããããããªãé »ç¹ã«ãªãããšããããŸãã
察話çéçº
REPL ã§ example ãåãããã ãã§ã¯ãäœãé¢çœããã¯èŠããŸãããcode ã Lisp file ã«å ¥ããŠå®è¡ããwindow ãåºããŠãã ãããããããã° panel widget ã layout ãå€ãããšãããã®å€æŽã application ã®å®è¡äžã«å³åº§ã«åæ ãããã®ãåãããŸãã
ãŸãšã
楜ããã§ãã ãããäœéšè«ã application ã®å ±æãé æ ®ãªãã©ããã
Page source: ja/gui.md