Keep QTreeView sorted - qt

I have a QTreeView with 3 columns. After I remove an element from the tree model I use the following to try to keep it sorted:
sort(0, Qt::AscendingOrder);
I expected that would re-sort the whole tree using column 0 as the sorting key. However it's behaving weird, nodes appear repeated, etc. after that sort is executed. What's wrong?
What's the way to keep it sorted all the time?

Related

Can tree column be hidden programmatically in TreeTableView of JavaFX?

I have a useful TreeTableView GUI view definition builder and would like to use in on tabular data where I don't need drill downs. I tried ...
m_treeTableView.getTreeColumn().setVisible(false);
... but it doesn't hide the tree column. Any help?
getTreeColumn appears to be returning null regardless of the thread or delayed execution I call it from. However, the column exists at index zero in the TreeTableView vector of columns. Hiding it by index works fine but gives unpredictable results if drill-down is defined.
However, TreeTableView hides the column automatically and elegantly if no drill-down is defined - logical behaviour and exactly what I need.
Edit: getTreeColumn returns null even if the column is not null, but is at its default position, leftmost place. Otherwise it returns the column.

Iterate over expanded nodes of QTreeWidget

I have a QTreeWidget. Have to iterate through the nodes which are expanded. Tried with iterating with QTreeWidgetItemIterator it(<rootNode>, QTreeWidgetItemIterator::NotHidden). But it is giving all the nodes of the tree instead of just expanded ones.
Am I missing to set any flag in the iterator?
I am afraid there is no specific flag for expanded items (but you can get checked items, for instance, using flags, http://doc.qt.io/qt-4.8/qtreewidgetitemiterator.html).
But you can easily check if item is expanded or not while iterating, using QTreeWidgetItem::isExpanded()

Get column datatype, sort direction onload, change sort order on first click of header in tablesorter

I have a grid view, which has several columns, one of which is a numeric column. When the grid loads first time, the data on the numeric column gets sorted on the server side itself and gets rendered. I apply client side sorting on another column also using table sorter. Now, the requirement is, because the number column comes already sorted in ascending order, upon clicking the number column header should sort it in descending order first. How can I achieve this? I thought of doing it in the following way, but getting no help.
1. How to find out the data type of a column by giving column or index using table sorter?
2. Identify whether a column is already sorted on load and if so, the sort direction of a that column.
3. Sort that column (mentioned above) in descending order, upon first time header click of that column.
I did try with debug option of table sorter, but it is simply giving some alert message, which is not much helpful.
Any help would be really appreciated.
Set the initial sort order in tablesorter to be the same as what is returned back from the server. For example, say your numeric column is column zero and you are returning it back from the server in desc order. Use the following in the table sorter config:
sortList:[[0,1]]
This will tell tablesorter to sort the first column in descending order. Now that tablesorter knows how the data is sorted, the next time you click on this column to sort it, it will sort in ascending order (since it's currently sorted in descending order).

Flex 4 How do I access a specific cell by index?

I would like to edit a cell by the row and column indexes so essentially do the following:
advDataGrid[2][3] = "Dogs"
so that I am setting the data grid row 2 and column 3 to Dogs. I cannot for the life of me figure out how to do this!
Side note: I need this because I am trying to allow the user to copy a section of an excel file to a section of an AdvancedDataGrid like Google Docs does. I am using this idea to do it: http://mannu.livejournal.com/348299.html
Thanks! Any help will be greatly appreciated!
In general you want to operate on the dataProvider rather than the presentation (AdvancedDataGrid). So in your case, I would get the item associated with the specified row from your dataProvider and modify whichever element is specified to "Dogs". So something like this: adg.dataProvider[row].someColumnData = "Dogs"
EDIT: "someColumnData" refers to whatever property you have set for the column to display. So when you defined your AdvancedDataGrid's columns, you set the 4th column to use the "someColumnData" property of the items in your dataProvider, and you want to change the value in the 4th column, then you'd set it as described above. Hope that clarifies things.
Flex components are data driven, so you should modify the data provider of the grid.
What if you want to edit specific individual cells, eg I want to to keep running totals of some cells in other cells, IE: as a user edits I update whole columns.
Surely their must be a way to walk the array and get Column4.row6 = something.

AdvancedDataGrid (grouping) quick jump to row

I have a problem with the AdvancedDataGrid widget. When the dataProvider is an ArrayCollection (of arrays), the nth array (within the collection) is also the nth row within the grid, and I can jump and display the i-th row by scripting
adg.selectedIndex = i;
adg.scrollToIndex(i);
now, when I add a Grouping, the dataProvider ends up being a GroupingCollection2, and now the index in the dataprovider's source does not correspond to the index in the adg anymore (which is understandable, because it's being grouped).
How can I select and display a row in grouped data efficiently? Currently, I have to traverse the adg and compare each found item with its data attributes in order to find the correct index of the row within the adg, and jump to it like above. This process is very slow. Any thoughts?
edited later:
We already used a caching object as Shaun suggests, but it still didn't compensate for the search times. In order to fully construct a sorting of a list of things (which this problem equates to, as the list is completely reordered by the grouping), you always have to know the entire set. In the end we didn't solve that problem. The project is over now. I will accept Shaun's answer if no one knows a better way in three days.
Depending on what values your comparing against you can store the objects in a dictionary with the lookup using the property/properties that would be searched for, this way you have a constant time look-up for the object (no need to look at every single item). Say for example your using a property called id on an object then you can create an AS object like
var idLookup:Object = {};
for(myObject in objects)
idLookup[myObject.id] = myObject;
//Say you want multiple properties
//idLookup[myObject.id]={};
//idLookup[myObject.id][myObject.otherProp] = myObject;
now say the user types in an id you go into the idLookup object at that id property and retrieve the object:
var myObject:Object = idLookup[userInput.text];
myAdg.expandItem(myObject, true);
now when you want to get an object by id you can just do
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/controls/AdvancedDataGrid.html#expandItem()
I haven't done any thorough testing of this directly, but use a similar concept for doing quick look-ups for advanced filtering. Let me know if this helps at all or is going in the wrong direction. Also if you could clarify a bit more in terms of what types/number of values you need to lookup and if there's the possibility for multiple matches etc. I may be able to provide a better answer.
Good luck,
Shaun

Resources