我试图使用GTK3和WebKit在Haskell中创建一个简单的应用程序。此代码创建并显示一个内部包含WebView
的窗口,每次按下一个键时都会显示一个随机数。
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
当我在GHCi(7.8.3)中运行它时,它运行正常。然而,当我再次运行而不退出GHCi时,WebView
从未显示任何东西 - 只是纯白色区域。这令人沮丧,因为我喜欢修改GHCi中的代码。
当然,如果我不使用forkOS
并在主线程中运行整个事情,一切正常。这个限制的原因是什么(我认为所有GTK函数都被认为是“主要”线程是initGUI
被调用的那个),并且能以某种方式克服它吗?
答案 0 :(得分:1)
如果它像python一样(我不知道haskell),你应该将gtk main loop
保留在main thread
。
在您的第二个主题调用g_idle_add中,使用回调功能对gtk进行更改,transport data between
使用second thread
和gtk
进行更改。你应该在gtk main
之前开始你的非主线程,这样它就不会被阻止。
我确定haskell中有g_idle_add
的绑定。还有g_timeout_add也适用于此。
这一切都与gtk不是线程安全有关。