如何在gtk2hs中做简单的ComboBoxEntry?

时间:2011-02-26 17:37:55

标签: haskell gtk gtk2hs

我使用下面的代码改编自教程。它显示了下拉列表中的两个选项,但是当我选择一个时,它会在控制台上显示错误:

(组合:12158):Gtk-CRITICAL **:IA__gtk_entry_set_text:断言`text!= NULL'失败

import Graphics.UI.Gtk
import Graphics.UI.Gtk.Gdk.EventM
import Graphics.UI.Gtk.Gdk.GC

main = do
  initGUI
  window <- windowNew
  window `onDestroy` mainQuit
  windowSetDefaultSize window 800 600
  windowSetPosition window WinPosCenter

  store <- listStoreNew ["one", "two"]
  combo <- comboBoxEntryNewWithModel store
  ren <- cellRendererTextNew
  cellLayoutPackEnd combo ren False
  cellLayoutSetAttributes combo ren store
    (\txt -> [cellText := txt])
  containerAdd window combo

  widgetShowAll window
  mainGUI

3 个答案:

答案 0 :(得分:2)

您正在尝试添加渲染器并设置其属性,这一切都很好。但是你没有告诉ComboBoxEntry应该最终编辑文本的位置。 Gtk +开发人员没有使用回调函数来提取这个文本,这就是Gtk2Hs(以及你的例子)。 Gtk +使用列号来引用一行数据中的特定数据,而不是回调。模型上的大多数特殊函数都使用列号,因为在C语言中使用它们比使用回调函数更容易。在Gtk2Hs中,您可以在任何其他属性映射的基础上添加列号。我已修改您的示例以声明ColumnId常量(可以使用您尚未为模型使用的任何整数)。 Gtk2Hs总是使用回调函数,因此我们必须将提取函数id与此列号相关联。第三个修改是告诉ComboBoxEntry使用此列号作为它的文本源。我保留了代码的一部分插入文本渲染器,但将其属性设置为常量。因此,文本形成您的商店,并且常量“&lt; - 您的选择”将显示在每一行中。

import Graphics.UI.Gtk
import Graphics.UI.Gtk.Gdk.EventM
import Graphics.UI.Gtk.Gdk.GC

textColumn :: ColumnId String String
textColumn = makeColumnIdString 0

main = do
  initGUI
  window <- windowNew
  window `onDestroy` mainQuit
  windowSetDefaultSize window 800 600
  windowSetPosition window WinPosCenter

  store <- listStoreNew ["one", "two"]
  customStoreSetColumn store textColumn id -- set the extraction function
  combo <- comboBoxEntryNewWithModel store
  comboBoxEntrySetTextColumn combo textColumn -- set which column should be used
  ren <- cellRendererTextNew
  cellLayoutPackEnd combo ren False
  cellLayoutSetAttributes combo ren store
    (\txt -> [cellText := "<-- your choice"])
  containerAdd window combo

  widgetShowAll window
  mainGUI

答案 1 :(得分:1)

使用ComboBoxEntry时,需要明确设置文本列。从理论上讲,你应该能够打电话给comboBoxEntrySetTextColumn,但我无法做到这一点。不过,我能够做到以下几点:

import Graphics.UI.Gtk
import Graphics.UI.Gtk.Gdk.EventM
import Graphics.UI.Gtk.Gdk.GC
import Control.Monad

main = do
  initGUI
  window <- windowNew
  window `onDestroy` mainQuit
  windowSetDefaultSize window 800 600
  windowSetPosition window WinPosCenter

  combo <- comboBoxEntryNewText
  store <- comboBoxEntrySetModelText combo
  mapM_ (listStoreAppend store) ["one", "two"]

  containerAdd window combo
  widgetShowAll window
  mainGUI

不同之处在于,当从comboBoxEntryNewText创建ComboBoxEntry时,它已经设置为使用带有相应文本列的ListStore String。它也有一个渲染器,所以你也不需要设置它。一个很大的缺点是它也设置了模型存储,所以如果你打算使用与另一个小部件共享的商店,你需要在这里创建它。

我怀疑comboBoxEntrySetModelText名称错误,看起来应该是“getModelText”。

答案 2 :(得分:0)

非常感谢@Axel!

使用新的gtk3库进行更新

import           Control.Monad.IO.Class     (liftIO)
import qualified Data.Text                  as T
import           Graphics.UI.Gtk
import           Graphics.UI.Gtk.Gdk.EventM

textColumn :: ColumnId String T.Text
textColumn = makeColumnIdString 0

main = do
  initGUI
  window <- windowNew
  window `on` deleteEvent $ liftIO mainQuit >> return False
  windowSetDefaultSize window 800 600
  windowSetPosition window WinPosCenter

  store <- listStoreNew ["one", "two"]
  customStoreSetColumn store textColumn (\x -> T.pack $ "1") -- set the extraction function
  combo <- comboBoxNewWithModelAndEntry store
  comboBoxSetEntryTextColumn combo textColumn -- set which column should be used
  ren <- cellRendererTextNew
  cellLayoutPackEnd combo ren False
  cellLayoutSetAttributes combo ren store
    (\txt -> [cellText := "<-- your choice"])
  containerAdd window combo

  widgetShowAll window
  mainGUI