Shinmera / qtools

Qtools is a collection of utilities to aid development with CommonQt
https://shinmera.github.io/qtools
zlib License
209 stars 17 forks source link

q+:exec failing #28

Open nchodosh opened 6 years ago

nchodosh commented 6 years ago

I'm using SBCL 1.3.20 (on Ubuntu 16.04) and I sporadically get the following error when using with-main-window

A simple application lsuch as following:

(define-widget notepad (QWidget)
  ())

(define-subwidget (notepad text-edit) (q+:make-qtextedit))

(define-subwidget (notepad quit-button) 
    (q+:make-qpushbutton "&Quit" notepad))

(define-subwidget (notepad layout) (q+:make-qvboxlayout notepad)
  (q+:add-widget layout text-edit)
  (q+:add-widget layout quit-button))

(define-slot (notepad quit) ()
  (declare (connected quit-button (released)))
   (q+:close notepad))

works the first time I run it. However if the application terminates with an error, or I change the definition of a slot, the next call to qt+:exec starts failing with the error: "QApplicaiton::exec: Must be called from the main thread".

Shinmera commented 6 years ago

Are you using C-c C-c or similar to evaluate your with-main-window form? This spawns a new thread every time, which Qt cannot deal with. You must always launch it from the same thread, such as the REPL thread.

nchodosh commented 6 years ago

No I always launch it from the REPL by evaluating a function which uses with-main-window. If the app exits normally I can re-launch it. I only have the issue after aborting the thread when an error is thrown.

Shinmera commented 6 years ago

In that case it's possible that the unwind leaves Qt in an unfavourable state, making it unable to restart. I've observed this myself occasionally, but don't have any idea on what exactly happens or how to remedy it, aside from the advice of: don't cause errors outside of callbacks.

nchodosh commented 6 years ago

I see, thanks!

phoe commented 5 years ago

Clarification: you can cause errors outside of callbacks, but when you attempt to remedy them, you must not use the toplevel ABORT restart to recover from callbacks - this will render your Lisp image unable to use Qt, as the *inferior-lisp* buffer will say something like QApplication::exec: The event loop is already running and the Qt execution will fail.

Use some of the available Abort smoke callback restarts to recover from these errors.