Ich versuche eine einfache App in Haskell mit GTK3 und WebKit zu machen. Dieser Code erstellt und zeigt ein Fenster mit einer WebView
Innenseite, die bei jedem Tastendruck eine Zufallszahl anzeigt.Wie kann ich WebKitGTK sicher von einem gegabelten Thread verwenden?
import Control.Monad.Trans (lift)
import Control.Concurrent (forkOS)
import System.Random (randomIO)
import Graphics.UI.Gtk -- gtk3
import Graphics.UI.Gtk.WebKit.WebView -- webkitgtk3
main = forkOS $ do
-- Init GTK.
initGUI
-- Create a window which would finish the GTK loop
-- after being closed.
window <- windowNew
window `after` objectDestroy $
mainQuit
-- Create a WebView inside.
webView <- webViewNew
set window [containerChild := webView]
-- Make the WebView display a random number on key press.
webView `on` keyReleaseEvent $ lift $ do
x <- randomIO :: IO Int
webViewLoadString webView (show x) Nothing Nothing ""
return True
-- Run GTK.
widgetShowAll window
mainGUI
Wenn ich es in GHCi (7.8.3) ausführen, funktioniert es gut. Jedoch, wenn ich es wieder laufen lasse, ohne GHCi zu verlassen, zeigt der WebView
nie etwas - einfach nur weißen Bereich. Das ist ärgerlich, da ich gerne mit Code in GHCi bastele.
Natürlich funktioniert alles gut, wenn ich 10 nicht benutze und das Ganze im Hauptthread ablaufen lasse. Was ist der Grund für diese Einschränkung (ich dachte, dass alle GTK-Funktionen der "Haupt" -Thread sind, der derjenige ist, in dem initGUI
aufgerufen wurde), und kann es irgendwie überwunden werden?
Möglicherweise müssen Sie explizit im gebundenen Thread mit 'Control.Concurrent.runInBoundThread' ausführen. – vivian
@vivian: Könnten Sie das weiter ausbauen? Ich dachte darüber nach, aber das Hinzufügen von 'runInBoundThread' direkt vor oder nach' forkOS' half nicht, und das Hinzufügen von 'print = << isCurrentThreadBound' zeigte, dass der Thread bereits begrenzt war. – Artyom
Funktioniert es außerhalb von GHCi wie erwartet? Wahrscheinlich wird eine Ereignisschleife gestoppt und nicht erneut gestartet, wenn Sie sie zweimal innerhalb eines einzelnen Prozesses ausführen. –