3

这就是我目前从林间空地文件初始化树视图的方式(删除了无趣的部分)

tree_view <- xmlGetWidget xml castToTreeView "tree_view"

为方便起见,如何使用已填充文本字段中的文本向 tree_view 添加新条目?

text <- get text_field entryText

有人可以帮助我吗?

谢谢

4

3 回答 3

8

根据您的描述,我假设您有一个树视图,但没有正确设置它。如果您不将 GTK 树视图连接到其他几个小部件,则它一文不值。

  • 树模型,它保存要在树视图中显示的数据。树模型可以是列表存储,将数据存储为列表,也可以是树存储,将数据存储为树,节点包含子节点。在您的情况下,您可能需要创建一个 ListStore:

    store <- listStoreNew String
    

    树模型可以存储任何类型的数据,包括复杂的自定义数据类型。

  • 要显示的每条数据的树视图列。在这种情况下,我们只需要一列,因为我们希望每行显示一个字符串:

    column <- treeViewColumnNew
    
  • 树视图列必须知道要显示哪些数据以及如何显示它(作为文本、作为复选框、作为图片......)所以我们需要一个单元格渲染器。单元格渲染器将从树模型中的每一行获取一条数据,并将其显示在给定的列中。为了显示文本,需要一个 CellRendererText。还有其他类型的单元格渲染器用于以其他形式显示数据(例如用于 True/False 值的 CellRendererToggle)。

    -- Create a cell renderer for displaying text
    cell <- cellRendererTextNew
    -- Add the cell renderer to the column. A column may display one or more
    -- pieces of data; just pack the cell renderers into the column
    cellLayoutPackStart column cell True
    -- Let the cell renderer know where it has to get the data from
    -- (in this case, the only element of each row). Note that we
    -- want to display some text
    cellLayoutSetAttributes column cell store $ \row -> [ cellText := row ]
    

接下来,将该列插入到树视图中。如果您不这样做,该列将不会显示!

    -- Insert the column into the tree view
    _ <- treeViewAppendColumn tree_view column
    -- Optional: Give a header/title to the column
    treeViewColumnSetTitle column "My data"

最后但同样重要的是:将树视图连接到树模型:

    treeViewSetModel tree_view store

现在您应该在树视图中看到一个空列。请参阅http://hackage.haskell.org/package/gtk上的 gtk 包的文档,了解如何在树模型(listStoreAppend、listStoreRemove、listStoreGetValue 等)中插入、删除和获取数据。

请注意,每个树模型都有一个类型,并且只能使用该类型的数据(但您可以使用任何数据类型,甚至是您自己的数据类型,因此您确实可以存储和显示复杂数据行,前提是您正确设置了每个树视图列)。否则编译程序时会出现类型错误。

于 2012-05-24T22:38:16.197 回答
1

TreeView是一个

“显示任何实现 TreeModel 接口的对象的小部件。”

所以需要treeViewGetModel、treeViewSetModel来获取TreeModel。

我希望您需要的TreeModel接口是 TreeStore:

提供了两个实现 TreeModel 接口的通用模型:TreeStore 和 ListStore。要使用这些,开发人员只需根据需要将数据插入这些模型中。

TreeStore 有treeStoreInsert

于 2012-05-24T17:05:39.323 回答
0

如果你像这样初始化你的树存储(只是传递一个空列表),Haskell 不会知道它的确切类型,并且会说存储的类型是“TreeStore (GHC.Prim.Any *)”,这不是你想要什么。

TreeStores 比 ListStores 更复杂,因为它们不仅必须包含数据,还必须包含其层次结构(父节点和子节点)。

参见 treeStoreNew 的定义:

    treeStoreNew :: Forest a -> IO (TreeStore a)

TreeStores 拥有一个类型为“a”的“森林”(整数、字符串等)。Forest 类型在模块 Data.Tree 中定义,因此您必须导入此模​​块:

    import Data.Tree

森林只是“树 a”的列表,这意味着数据类型“树”包含“a”类型的值。也就是说,为了正确设置树存储,如果要存储字符串,则必须执行以下操作:

    let id :: [Tree String]
        id = []
    store <- treeStoreNew id

如果您查看商店的类型(在 GHCi 提示符处),您会发现它是正确的:

    :t store
    store :: TreeStore String

要在“[]”(顶层,没有父级)插入一行,如果顶层已经有一些行(这是(-1)的含义),则将其附加到末尾,例如字符串“约翰”:

    treeStoreInsert store [] (-1) "John"

该行将插入到路径 [0]。在 GHCi 检查它:

    treeStoreGetTree store [0] >>= print

这将给出“节点 {rootLabel = “John”,subForest = []}”。

要插入“John”的孩子,例如“Smith”:

    treeStoreInsert store [0] (-1) "Smith"

树现在将包含一个父项和一个子项(使用 GHCi 检查):

    treeStoreGetTree store [0] >>= print

现在将输出“Node {rootLabel = "John", subForest = [Node {rootLabel = "Smith", subForest = []}]}"。

最后,

    treeStoreGetTree store [0,0] >>= print

将只显示孩子:节点 {rootLabel = "Smith", subForest = []}

请参阅文档以了解有关该主题的更多信息。

于 2012-05-25T22:47:34.977 回答