(in-package :cl-smoke.qt.core) (defclass single-shot-timer (qt:object) ((function :initarg :function :type function) (timer-id :type integer)) (:metaclass cxx:class)) (defvar *single-shot-timers* nil "Pending timers.") (defun single-shot (function &optional (timeout 0)) "Run FUNCTION after TIMEOUT seconds, or as soon as all window events have been processed when TIMEOUT is 0. Equivalent to QTimer::singleShot, but calls a function instead of a slot." (let ((timer (make-instance 'single-shot-timer :function function))) (setf (slot-value timer 'timer-id) (cxx:start-timer timer (floor timeout 100))) (push timer *single-shot-timers*))) (defmacro qt:do-delayed-initialize (&body body) "Run body when the event loop starts. http://techbase.kde.org/Development/Tutorials/Common_Programming_Mistakes#Delayed_Initialization" `(single-shot #'(lambda () ,@body))) (defmethod cxx:timer-event ((timer single-shot-timer) event) (declare (ignore event)) (cxx:kill-timer timer (slot-value timer 'timer-id)) (funcall (slot-value timer 'function)) (remove timer *single-shot-timers*))