Ich habe keine Lösung gefunden, die ClojureREPL mit Qt im Web zu verwenden. Grundsätzlich ist das Problem, dass die REPL hängt, sobald Sie QApplication/exec aufrufen, um die Benutzeroberfläche anzuzeigen. Du kannst nicht C-c C-c zurück in die REPL, und das Schließen des aktiven Qt-Fensters scheint den gesamten Clojure-Prozess zu beenden.Wie kann ich die Clojure REPL zusammen mit Qt Jambi verwenden?
Der einfache Aufruf von QApplication/processEvents aus einem Agenten heraus ist nicht möglich, es sei denn, der Agent wird in genau demselben Thread ausgeführt, in dem Sie die Qt-Widgets erstellt haben. Ich habe zwei Tage gebraucht, um das herauszufinden und ich habe gesehen, dass andere das gleiche Problem haben, aber ohne eine Lösung. hier also ist mein, in Code:
(add-classpath "file:///usr/share/java/qtjambi.jar")
(ns qt4-demo
(:import (com.trolltech.qt.gui QApplication QPushButton QFont QFont$Weight)
(com.trolltech.qt.core QCoreApplication)
(java.util Timer TimerTask)
(java.util.concurrent ScheduledThreadPoolExecutor TimeUnit))
(:require swank.core))
(defn init []
(QApplication/initialize (make-array String 0)))
(def *gui-thread* (new java.util.concurrent.ScheduledThreadPoolExecutor 1))
(def *gui-update-task* nil)
(def *app* (ref nil))
(defn update-gui []
(println "Updating GUI")
(QApplication/processEvents))
(defn exec []
(.remove *gui-thread* update-gui)
(def *gui-update-task* (.scheduleAtFixedRate *gui-thread* update-gui 0 150 (. TimeUnit MILLISECONDS))))
(defn stop []
(.remove *gui-thread* update-gui)
(.cancel *gui-update-task*))
(defmacro qt4 [& rest]
`(do
(try (init) (catch RuntimeException e# (println e#)))
[email protected]
))
(defmacro with-gui-thread [& body]
`(.get (.schedule *gui-thread* (fn [] (do [email protected])) (long 0) (. TimeUnit MILLISECONDS))))
(defn hello-world []
(with-gui-thread
(qt4
(let [app (QCoreApplication/instance)
button (new QPushButton "Go Clojure Go")]
(dosync (ref-set *app* app))
(doto button
(.resize 250 100)
(.setFont (new QFont "Deja Vu Sans" 18 (.. QFont$Weight Bold value)))
(.setWindowTitle "Go Clojure Go")
(.show)))))
(exec))
Grundsätzlich verwendet es die ScheduledThreadPoolExecutor Klasse, um alle Qt-Code auszuführen. Sie können das With-GUI-Thread-Makro verwenden, um das Aufrufen von Funktionen innerhalb des Threads zu erleichtern. Dies ermöglicht es, die Qt UI im laufenden Betrieb ohne Neukompilierung zu ändern.
Ja, ich musste das gleiche tun. – levand
Ich weiß nichts über QT. Aber warum willst du das machen? Clojure hat Zugang zu Swing, einem sehr leistungsfähigen und vielseitigen GUI-Framework. Verbinden Sie sich mit einer bereits vorhandenen QT-GUI? –
QT ist in vielerlei Hinsicht besser als Swing, einschließlich Performance und nativem Look-and-Feel. – levand