www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Retrieving Column Data from a ListStore?

reply Ron Tarrant <rontarrant gmail.com> writes:
Another thing I've been struggling with is fetching data from a 
TreeIter. Getting the iter itself is no problem, but when it 
comes to getting the contents of a specific column within the 
iter, none of the methods I've tried have worked. In fact, it 
almost seems like none of them are implemented.

I've written a callback function named onChanged() in the 
MyComboBox class that gets the TreeIter, but that's all I can get 
working. If anyone knows how to grab data from column 2 of the 
iter (see the MyListStore class at the bottom for the structure 
of the store) I'd be ever so grateful if you could fill in 
whatever else would be needed in that callback.

Here's the code:

```
import std.stdio;
import std.conv;

import gtk.MainWindow;
import gtk.Main;
import gtk.Box;
import gtk.Widget;
import gtk.ComboBox;
import gtk.CellRendererText;
import gtk.ListStore;
import gtk.TreeIter;

void main(string[] args)
{
	Main.init(args);

	TestRigWindow myTestRig = new TestRigWindow("Test Rig");
	
	Main.run();
	
} // main()


class TestRigWindow : MainWindow
{
	AppBox appBox;
	
	this(string title)
	{
		super(title);
		addOnDestroy(&quitApp);
		
		appBox = new AppBox();
		add(appBox);
		
		showAll();

	} // this() CONSTRUCTOR
	
		
	void quitApp(Widget widget)
	{
		writeln("Bye.");
		Main.quit();
		
	} // quitApp()

} // class myAppWindow


class AppBox : Box
{
	MyComboBox myComboBox;
	
	this()
	{
		super(Orientation.VERTICAL, 10);
		
		myComboBox = new MyComboBox();
		packStart(myComboBox, false, false, 0);

	} // this()

} // class AppBox


class MyComboBox : ComboBox
{
	MyListStore myListStore;
	CellRendererText renderer;
	
	this()
	{
		super(false);
		myListStore = new MyListStore();
		setModel(myListStore);
		
		renderer = new CellRendererText();
		packStart(renderer, true);
		addAttribute(renderer, "text", 1);
		setActive(0);
		
		addOnChanged(&onChanged);

	} // this()
	
	
	void onChanged(ComboBox cb)
	{
		TreeIter treeIter;
		string data;
		
		writeln("active: ", getActive());
		getActiveIter(treeIter);
		
		
	} // onChanged()
	
} // class MyComboBox


class MyListStore : ListStore
{
	TreeIter treeIter;
	string[] items = ["bikes", "bumps", "deer", "falling rocks", 
"road crews", "cattle"];
	
	this()
	{
		super([GType.INT, GType.STRING, GType.STRING]);
		
		for(int i = 0; i < items.length; i++)
		{
			treeIter = createIter();
			
			setValue(treeIter, 0, i + 10);
			setValue(treeIter, 1, items[i]);
			setValue(treeIter, 2, items[i] ~ " Extra data " ~ 
to!string(i));
		}

	} // this()
	
} // class MyListStore

```
Apr 24 2019
parent reply Mike Wey <mike-wey example.com> writes:
On 24-04-2019 16:38, Ron Tarrant wrote:
 Another thing I've been struggling with is fetching data from a 
 TreeIter. Getting the iter itself is no problem, but when it comes to 
 getting the contents of a specific column within the iter, none of the 
 methods I've tried have worked. In fact, it almost seems like none of 
 them are implemented.
 
 I've written a callback function named onChanged() in the MyComboBox 
 class that gets the TreeIter, but that's all I can get working. If 
 anyone knows how to grab data from column 2 of the iter (see the 
 MyListStore class at the bottom for the structure of the store) I'd be 
 ever so grateful if you could fill in whatever else would be needed in 
 that callback.
 
 Here's the code:
 
 ```
 ...
 
 ```
The ListStore/TreeModel provides functions to retrieve the data, `gtk.TreeModelIF.TreeModelIF.getValue`. A TreeIter indicates the row these kind of function apply to. -- Mike Wey
Apr 24 2019
parent reply Ron Tarrant <rontarrant gmail.com> writes:
On Wednesday, 24 April 2019 at 15:13:29 UTC, Mike Wey wrote:

 The ListStore/TreeModel provides functions to retrieve the 
 data, `gtk.TreeModelIF.TreeModelIF.getValue`.

 A TreeIter indicates the row these kind of function apply to.
Well, this is embarrassing. I tried that earlier and it didn't work. Now it does. Go figure. (sigh) Thanks, Mike. For anyone else who comes along looking for the same answer, here's what I did: ``` void onChanged(ComboBox cb) { TreeIter treeIter; TreeModelIF treeModel; string data; writeln("active: ", getActive()); getActiveIter(treeIter); data = getModel().getValueString(treeIter, 1); writeln(data); } // onChanged() ```
Apr 24 2019
parent reply number <putimalitze gmx.de> writes:
On Wednesday, 24 April 2019 at 18:56:50 UTC, Ron Tarrant wrote:
 For anyone else who comes along looking for the same answer, 
 here's what I did:
I'm trying to do it with multi-selection. It works now but I wonder if it's right to just create a dummy TreeModelIF to call getSelectedRows()? Same question for creating a TreeIter to call getIter()? ``` import std.stdio; import gtk.Main; import gtk.MainWindow; import gtk.TreeView; import gtk.CellRendererText; import gtk.TreeViewColumn; import gtk.ListStore; import gtk.TreeStore; import gtk.TreeIter; import gtk.TreeSelection; import gtk.TreePath; void main(string[] args) { Main.init(args); MainWindow window = new MainWindow("title"); window.setSizeRequest(400, 200); TreeView treeView = new TreeView(); CellRendererText cellRendererText; TreeViewColumn treeViewColumn; CellRendererText cellRendererTextA = new CellRendererText(); CellRendererText cellRendererTextB = new CellRendererText(); treeViewColumn = new TreeViewColumn(); treeViewColumn.setTitle("A and B"); treeViewColumn.packStart(cellRendererTextA, true); treeViewColumn.packStart(cellRendererTextB, true); treeViewColumn.addAttribute(cellRendererTextA, "text", 0); treeViewColumn.addAttribute(cellRendererTextB, "text", 1); treeView.appendColumn(treeViewColumn); cellRendererText = new CellRendererText(); treeViewColumn = new TreeViewColumn("C", cellRendererText, "text", 2); treeView.appendColumn(treeViewColumn); //ListStore listStore = new ListStore([GType.STRING, GType.STRING, GType.STRING]); TreeStore treeStore = new TreeStore([GType.STRING, GType.STRING, GType.STRING]); treeView.setModel(treeStore); TreeIter treeIter; treeIter = treeStore.createIter(); treeStore.setValue(treeIter, 0, "a"); treeStore.setValue(treeIter, 1, "b"); treeStore.setValue(treeIter, 2, "c"); treeIter = treeStore.createIter(); treeStore.setValue(treeIter, 0, "a2"); treeStore.setValue(treeIter, 1, "b2"); treeStore.setValue(treeIter, 2, "c2"); TreeSelection treeSelection = treeView.getSelection(); treeSelection.setMode(SelectionMode.MULTIPLE); treeSelection.addOnChanged(delegate void(TreeSelection treeSelection) { writeln("----"); if (treeSelection.getMode() == SelectionMode.MULTIPLE) { import gtk.TreeModelIF; TreeModelIF tm; //writeln(tm); TreePath[] treePaths = treeSelection.getSelectedRows(tm); writeln("nb selected: ", treeSelection.countSelectedRows()); if (treePaths.length) { foreach (i, treePath; treePaths) { writefln("path(%s) : %s", i, treePath); TreeIter treeIter = new TreeIter(); treeStore.getIter(treeIter, treePath); writefln("%s, %s, %s" , treeStore.getValueString(treeIter, 0) , treeStore.getValueString(treeIter, 1) , treeStore.getValueString(treeIter, 2) ); } } else { writeln("nothing"); } } else { TreeIter treeIter = treeSelection.getSelected(); if (treeIter) { writefln("%s, %s, %s" , treeStore.getValueString(treeIter, 0) , treeStore.getValueString(treeIter, 1) , treeStore.getValueString(treeIter, 2) ); } else { writeln("nothing"); } } }); window.add(treeView); window.showAll(); Main.run(); } ```
Apr 25 2019
parent reply Ron Tarrant <rontarrant gmail.com> writes:
On Thursday, 25 April 2019 at 11:29:04 UTC, number wrote:

 I'm trying to do it with multi-selection. It works now but I 
 wonder if it's right to just create a dummy TreeModelIF to call 
 getSelectedRows()? Same question for creating a TreeIter to 
 call getIter()?
Whatever works, I guess. Just looking over what you've got, I don't really see anyway around creating the dummy for either one since they each have to be passed into functions.
Apr 25 2019
parent number <putimalitze gmx.de> writes:
On Thursday, 25 April 2019 at 15:16:03 UTC, Ron Tarrant wrote:
 On Thursday, 25 April 2019 at 11:29:04 UTC, number wrote:

 I'm trying to do it with multi-selection. It works now but I 
 wonder if it's right to just create a dummy TreeModelIF to 
 call getSelectedRows()? Same question for creating a TreeIter 
 to call getIter()?
Whatever works, I guess. Just looking over what you've got, I don't really see anyway around creating the dummy for either one since they each have to be passed into functions.
I wasn't sure if it wants the actual tree model used with the tree view, but passing my treeStore didn't work, so I used a dummy. Don't know what it's for though.
Apr 25 2019