8

我正在尝试使用 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被调用的线程),并且可以以某种方式克服它吗?

4

1 回答 1

1

如果它像 python(我不知道 haskell)一样工作,你应该gtk main loopmain thread.

在您的第二个线程中调用g_idle_add并使用回调进行更改,以使用 gtk 和transport data between您的second thread, 和gtk. 您应该先启动非主线程,gtk main以免被阻塞。

我确定g_idle_add在haskell中有一个绑定。还有 g_timeout_add 也适用于此。

这一切都与 gtk 不是线程安全的有关。

于 2014-08-04T21:20:21.670 回答