这就是我目前从林间空地文件初始化树视图的方式(删除了无趣的部分)
tree_view <- xmlGetWidget xml castToTreeView "tree_view"
为方便起见,如何使用已填充文本字段中的文本向 tree_view 添加新条目?
text <- get text_field entryText
有人可以帮助我吗?
谢谢
这就是我目前从林间空地文件初始化树视图的方式(删除了无趣的部分)
tree_view <- xmlGetWidget xml castToTreeView "tree_view"
为方便起见,如何使用已填充文本字段中的文本向 tree_view 添加新条目?
text <- get text_field entryText
有人可以帮助我吗?
谢谢
根据您的描述,我假设您有一个树视图,但没有正确设置它。如果您不将 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 等)中插入、删除和获取数据。
请注意,每个树模型都有一个类型,并且只能使用该类型的数据(但您可以使用任何数据类型,甚至是您自己的数据类型,因此您确实可以存储和显示复杂数据行,前提是您正确设置了每个树视图列)。否则编译程序时会出现类型错误。
TreeView是一个
“显示任何实现 TreeModel 接口的对象的小部件。”
所以需要treeViewGetModel、treeViewSetModel来获取TreeModel。
我希望您需要的TreeModel接口是 TreeStore:
提供了两个实现 TreeModel 接口的通用模型:TreeStore 和 ListStore。要使用这些,开发人员只需根据需要将数据插入这些模型中。
TreeStore 有treeStoreInsert。
如果你像这样初始化你的树存储(只是传递一个空列表),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 = []}
请参阅文档以了解有关该主题的更多信息。