无法获得gtk2 CellRendererCombo来显示任何内容

时间:2016-02-02 07:30:03

标签: haskell gtk gtk2 gtk2hs

我无法获取gtk的单元格渲染器组合框来显示任何选项。我需要为树中的每一行使用不同的模型,这应该可以使用cellComboTextModel。我的结果是组合框渲染器完全为空。

这是一个简化的例子:

{-# OPTIONS_GHC -Wall #-}

module Main ( main ) where

import Graphics.UI.Gtk ( AttrOp( (:=) ) )
import qualified Graphics.UI.Gtk as Gtk
import System.Glib.Signals ( on )

-- the element in the list store
data ListElement =
  ListElement
  { leName :: String
  , leListStore :: Gtk.ListStore String
  }

makeMyTreeview :: IO Gtk.TreeView
makeMyTreeview = do
  -- make a list store with two elements

  -- the storage for each combo box cell renderer
  comboListStore0 <- Gtk.listStoreNew ["hi", "there"]
  comboListStore1 <- Gtk.listStoreNew ["A", "B", "C"]
  let elements =
        [ ListElement "joe" comboListStore0
        , ListElement "bob" comboListStore1
        ]

  listStore <- Gtk.listStoreNew elements :: IO (Gtk.ListStore ListElement)
  treeview <- Gtk.treeViewNewWithModel listStore :: IO Gtk.TreeView

  Gtk.treeViewSetHeadersVisible treeview True

  -- add some columns
  nameCol <- Gtk.treeViewColumnNew
  comboCol <- Gtk.treeViewColumnNew

  Gtk.treeViewColumnSetTitle nameCol "name"
  Gtk.treeViewColumnSetTitle comboCol "combo"

  -- add cell renderers
  nameRenderer <- Gtk.cellRendererTextNew
  comboRenderer <- Gtk.cellRendererComboNew

  Gtk.cellLayoutPackStart nameCol nameRenderer True
  Gtk.cellLayoutPackStart comboCol comboRenderer True

  _ <- Gtk.treeViewAppendColumn treeview nameCol
  _ <- Gtk.treeViewAppendColumn treeview comboCol

  -- this sets the name column strings
  Gtk.cellLayoutSetAttributes nameCol nameRenderer listStore $
    \x -> [Gtk.cellText := leName x ++ "!"]

  -- combo box
  Gtk.cellLayoutSetAttributes comboCol comboRenderer listStore $ \x ->
    [ Gtk.cellComboTextModel := ( leListStore x, Gtk.makeColumnIdString 0 :: Gtk.ColumnId String String
                                )
    , Gtk.cellMode := Gtk.CellRendererModeActivatable
    , Gtk.cellComboHasEntry := True
    ]

  -- an action when the combo box is edited
  _ <- on comboRenderer Gtk.edited $ \_treePath newVal -> do
    putStrLn "combo box is being edited (this never happens)"
    putStrLn $ "new value: " ++ newVal

  return treeview


main :: IO ()
main = do
  _ <- Gtk.initGUI
  win <- Gtk.windowNew
  _ <- Gtk.set win [ Gtk.containerBorderWidth := 8
                   , Gtk.windowTitle := "help"
                   ]
  treeview <- makeMyTreeview
  _ <- Gtk.set win [ Gtk.containerChild := treeview ]
  Gtk.widgetShowAll win
  Gtk.mainGUI

非常感谢任何见解。

编辑: 我想出了我所缺少的东西:

Gtk.treeModelSetColumn comboListStore0 (Gtk.makeColumnIdString 0) id
Gtk.treeModelSetColumn comboListStore1 (Gtk.makeColumnIdString 0) id

这将设置ListStore列ID,以便后面的行

Gtk.cellComboTextModel := (leListStore x, Gtk.makeColumnIdString 0 :: Gtk.ColumnId String String)

正确引用文本。这似乎不适用于GTK3

1 个答案:

答案 0 :(得分:1)

我想出了GTK3。 (请参阅上面的GTK2解决方案编辑。)对于GTK3,您必须使用editingStarted信号手动编辑组合框的列表库。不幸的是,这会导致GTK2的段错误。

以下是GTK3的完整工作代码

{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE PackageImports #-}

module Main ( main ) where

import qualified Data.Text as T
import "gtk3" Graphics.UI.Gtk ( AttrOp( (:=) ) )
import qualified "gtk3" Graphics.UI.Gtk as Gtk
import System.Glib.Signals ( on )

-- the element in the list store
data ListElement =
  ListElement
  { leName :: String
  , leListStore :: Gtk.ListStore String
  , leOptions :: [String]
  }

makeMyTreeview :: IO Gtk.TreeView
makeMyTreeview = do
  -- the storage for each combo box cell renderer
  comboListStore0 <- Gtk.listStoreNew []
  comboListStore1 <- Gtk.listStoreNew []
  Gtk.treeModelSetColumn comboListStore0 (Gtk.makeColumnIdString 0) id
  Gtk.treeModelSetColumn comboListStore1 (Gtk.makeColumnIdString 0) id
  let elements =
        [ ListElement "joe" comboListStore0 ["hi", "there"]
        , ListElement "bob" comboListStore1 ["A", "B", "C"]
        ]

  listStore <- Gtk.listStoreNew elements :: IO (Gtk.ListStore ListElement)
  treeview <- Gtk.treeViewNewWithModel listStore :: IO Gtk.TreeView

  Gtk.treeViewSetHeadersVisible treeview True

  -- add some columns
  nameCol <- Gtk.treeViewColumnNew
  comboCol <- Gtk.treeViewColumnNew

  Gtk.treeViewColumnSetTitle nameCol "name"
  Gtk.treeViewColumnSetTitle comboCol "combo"

  -- add cell renderers
  nameRenderer <- Gtk.cellRendererTextNew
  comboRenderer <- Gtk.cellRendererComboNew

  Gtk.cellLayoutPackStart nameCol nameRenderer True
  Gtk.cellLayoutPackStart comboCol comboRenderer True

  _ <- Gtk.treeViewAppendColumn treeview nameCol
  _ <- Gtk.treeViewAppendColumn treeview comboCol

  -- this sets the name column
  Gtk.cellLayoutSetAttributes nameCol nameRenderer listStore $
    \x -> [Gtk.cellText := leName x ++ "!"]

  Gtk.cellLayoutSetAttributes comboCol comboRenderer listStore $ \x ->
    [ Gtk.cellTextEditable := True
    , Gtk.cellComboTextModel := (leListStore x, Gtk.makeColumnIdString 0 :: Gtk.ColumnId String String)
    , Gtk.cellComboHasEntry := False
    ]

  -- here is where we will set the combo options!!!!
  _ <- on comboRenderer Gtk.editingStarted $ \widget treepath -> do
    case treepath of
      [k] -> do
        listElement <- Gtk.listStoreGetValue listStore k
        comboListStore <- Gtk.comboBoxSetModelText (Gtk.castToComboBox widget)
        mapM_ (Gtk.listStoreAppend comboListStore . T.pack) (leOptions listElement)
      ks -> error $ "bad treepath for liststore: " ++ show ks

  -- an action when the combo box is edited
  _ <- on comboRenderer Gtk.edited $ \_treePath newVal -> do
    putStrLn $ "combo box edited, new value: " ++ newVal

  return treeview


main :: IO ()
main = do
  _ <- Gtk.initGUI
  win <- Gtk.windowNew
  _ <- Gtk.set win [ Gtk.containerBorderWidth := 8
                   , Gtk.windowTitle := "help"
                   ]
  treeview <- makeMyTreeview
  _ <- Gtk.set win [ Gtk.containerChild := treeview ]
  Gtk.widgetShowAll win
  Gtk.mainGUI