0

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

(组合:12158):Gtk-CRITICAL **:IA__gtk_entry_set_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
4

3 回答 3

2

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

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
于 2011-02-27T15:57:00.710 回答
1

当您使用 aComboBoxEntry时,您需要明确设置 Text Column。理论上你应该可以打电话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

不同之处在于,当 ComboBoxEntry 从 中创建时comboBoxEntryNewText,它已经设置为将 aListStore String与适当的文本列一起使用。它也有一个渲染器,所以你也不需要设置它。一个很大的缺点是它还设置了模型存储,因此如果您打算使用与另一个小部件共享的存储,则需要在此处创建它。

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

于 2011-02-27T14:58:08.100 回答
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
于 2019-07-18T09:13:08.247 回答