【问题标题】:can't get gtk2 CellRendererCombo to display anything无法让 gtk2 CellRendererCombo 显示任何内容
【发布时间】:2016-02-02 07:30:03
【问题描述】:

我无法让 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 中不起作用

【问题讨论】:

    标签: haskell gtk gtk2 gtk2hs


    【解决方案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
    

    【讨论】:

    • 我不会接受这个答案,即使这样它也能解决我的问题,因为我从来没有真正找到问题的根源。
    猜你喜欢
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多