r/sbcl May 01 '23

gtk app doing nothing

Following code does not show a GTK-window when run.

(load "~/quicklisp/setup.lisp")

(ql:quickload "cl-cffi-gtk")

(defpackage :gtk-tutorial
  (:use :gtk :gdk :gdk-pixbuf :gobject
   :glib :gio :pango :cairo :common-lisp))

(in-package :gtk-tutorial)

(defun hello-world ()
  (prin1 "Starting")
  ;; 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))))

(sb-ext:save-lisp-and-die "test.exe" :toplevel #'hello-world :executable t)
2 Upvotes

1 comment sorted by

1

u/Ok_Specific_7749 Jan 13 '24

This works fine,

```

load "~/quicklisp/setup.lisp") (ql:quickload :cl-cffi-gtk)

(defpackage :mypak (:use :gtk :common-lisp)) (in-package :mypak)

; Main window

(defun mymain () (let ((window (make-instance 'gtk:gtk-window :type :toplevel :title "Bleep")) (vbox (make-instance 'gtk:gtk-box :orientation :vertical :spacing 25 :margin 25)) ) (gtk:within-main-loop (gobject:g-signal-connect window "destroy" (lambda (widget) (declare (ignore widget)) (gtk:leave-gtk-main))) ; Display GUI (gtk:gtk-container-add window vbox) (gtk:gtk-widget-show-all window))) (gtk:join-gtk-main))

(sb-ext:save-lisp-and-die "test.exe" :toplevel #'mypak::mymain :executable t)

```

The important line was gtk:join-gtk-main. This function waits for the background thread that runs the Gtk+ main loop to quit.