I need a hierarchical grid that shows data in columns for the parent rows as well as the child rows.
- a parent | 1234 | data | data |
a child | 2222 | data | data |
a child | 212 | data | data |
I've tried to make ADG work, but by default it has all columns except the grouping column blank for parent rows. I think I could use item renderers to push the data out there.
My blocking problem is that my grouping does not seem to work at all. I can see the data when I set dataProvider=MyArrayCollection, but
<mx:GroupingCollection id="GroupingCollection"
source="{this.specificReportData.gridData}">
<mx:Grouping label="childName">
<mx:GroupingField name="parentName" />
</mx:Grouping>
</mx:GroupingCollection>
does not work: no data appears. I've tried having an explicit "childname" column, and not having one. I've tried wrapping it in a HierarchicalCollectionView, but that doesn't work either. I've walked through the basic grouping tutorials and my code and data look like it follows the pattern.
Any ideas?
You must not include parents in your datasource. You need a datasource like this:
a child | 2222 | data | data | parentid | parentname
a child | 212 | data | data | parentid | parentname
And set the groupingfield to parentid or parentname. The grouping makes a hierarchy out of a flat datasource and thus creates the parents for you.
The answer is that the AdvancedDataGrid is not built to do what I want.
It is great at grouping data with common values; it is not good at grouping data where the actual parent elements exist as rows themselves. I also require the sorting and filtering apply to the parent elements only (based on their own data); any visible parent can show their children, and the children never sort.
My two-stage solution is first to process the data by iterating through it and creating an array of parent elements and adding a children array property to them that holds the child elements. Note that these are arrays of references; I am not copying the actual data.
Next, I apply any sorting and filtering to the parent array (perhaps by using an ArrayCollection wrapper) and iterate through the parents, copying the visible ones (and their children if the parent is marked expanded) to a display array. My grid them uses the display array as a simple (e.g. not grouped) dataProvider. A custom item renderer will indent the children and change the expanded property of the parent elements, which will regenerate the display array.
This is not only a simpler and more intuitive solution, it does not require a reader or maintainer to understand the idiosyncrasies of ADG (my motto: No Clever Code).
Thank you Thomas for trying. I'm giving your reply a +1 even though I'm not marking it as the answer.
Cheers
Related
Versions
pyqt5
python 3.6
Setup
I'm having a few issues with the QTreeView class.
The QTreeView is configured as:
treeView.setSelectionBehavior(QAbstractItemView.SelectRows)
treeView.setSelectionMode(QAbstractItemView.SingleSelection)
There are no custom style sheets on this QTreeView
I've implemented a custom model for the view, and the flags() definition is:
def flags(self, index):
if not index.isValid():
return 0
f = super(RecordTreeModel, self).flags(index)
f = f | Qt.ItemIsSelectable | Qt.ItemIsEnabled
return f
Is there anything else relevant to the situation? I'm not doing anything fancy with my model. No custom painting, no special selection requirements -- everything is straight out of basic model examples besides the way the data structure is accessed.
Issues
Row Selection
When clicking on any column besides the first column, the row will not be selected.
Column Hovering
When hovering over any column besides the first column, the row will not be highlighted
Child Hovering
No child rows are ever highlighted when the mouse hovers over them.
I've been banging my head (and google's search bar) against these problems for several hours, to no avail.
Please let me know if I can provide any additional information!
I'm trying to make a table-based interface as follows:
| QComboBox | QPushButton | Empty |
| Some data | Some data | QPushButton |
| Some data | Some data | Empty | (all additional rows resemble this one)
In the first row, I want a QComboBox with some selections that are defined based on the return value of another function, and the QPushButtons are attached to triggers which will insert or remove data.
Assuming I can generate the QComboBox and QPushButtons on my own, how can I get them to be inserted into the QTableView in those locations? I currently have a model which properly stores the data that need to be shown in the locations marked "Some data" and to return no data for the special or "Empty" locations, and I have a QStyledItemDelegate which is supposed to insert these widgets for me, but it only inserts them when I double click the field (which I suppose is the trigger for createEditor).
Figured it out.
QAbstractItemView (and by extension QTableView) have a method called setIndexWidget which can be used to place a widget in a location. By using that method, I can insert the appropriate widgets on initialization without relying on a delegate at all.
I'm working on a subclass of QAbstractItemModel that plugs into a QTreeView. It has a recursive Name = Value type structure - any index could have its own subtree. This is fine on the left side, because almost every tree view out there works that way. The problem is that sometimes I want a subtree only on the right side - a list of values. As I have it right now, it seems like it should work, but Qt is never calling rowCount() for the right side, and never realizing that there should be a subtree there.
The solution that I have right now is basically to create a separate model for that, and use setIndexWidget to give it a separate tree view every time this happens. That's fine, but I'd really like to get the subtrees showing up on the right without having to throw tree views all over the place. My model responds that there are subtrees over there, but Qt just never asks for them.
If this is a little unclear, this is the basic idea of what I want to accomplish:
- Root |
- Name 1 | Value
Name 2 | - Compound Value
| Sub-value 1
| Sub-value 2
Name 3 | + Compound Value (collapsed)
+ Name 4 | Value
As it is, the compound values will not get the +'s and -'s next to them because Qt never calls hasChildren() or rowCount() in that column, even though my model would return that yes, there are children, if it was asked.
If I end up having to give it a sub-tree view, that's fine. I'd just like to be sure that there's not a better way to do it first.
I'm trying to implement a dual Tree View my self, some thing like
+ a | A
+ b | + B
c | C
and from What I've seen you can make the space between Name 2 and Name 3 by returning empty data e.g. an empty string under the Name 2 which would enable you to have a + infront of it.
So something like this may help
def data(self, index, role):
...
if item.pathdepth() > 3 :
return " "
...
def flags(self, index)
...
if item.pathdepth() > 3 :
return Qt.Some_Role but not others
...
I don't know enough about the roles yet, but you could disable selection and editing so that the 'blanks' are not selectabe by the user.
But I haven't worked out how to get a tree in the second column.
I'm using the radgrid and I need to be able to add a row dynamically based on a certain condition. The table looks something like this:
|col0|col1|
|0,0 |1,0 |
|0,1 |1,1 |
|0,2 |1,2 |
But I want to be able to add pseudo-headers based on a condition:
|col0|col1|
|0,0 |1,0 |
|header |
|0,1 |1,1 |
|0,2 |1,2 |
The header row is not in the underlying data, I just want to add it if the condition is triggered. I don't think I can do this in the ItemTemplate itself, because I need to span all the columns, and this requires a separate table row. But I also can't find any way to accomplish it using code behind.
This seems so basic that I'm sure I'm missing something, but I don't know what it is. I'm also not at all attached to the idea of adding a row, if there's another way to accomplish what I'm trying to do.
Thanks in advance!
For posterity, I never found a way to do this, and ultimately threw out the RadGrid entirely and implemented the required layout with a repeater control that emits a table and rows, and I just emit an extra row for the header when necessary. I remain baffled that something so relatively straightforward does not appear to be possible with the RadGrid.
Let's say I have data structures that're something like this:
Public Class AttendenceRecord
Public CourseDate As Date
Public StudentsInAttendence As Integer
End Class
Public Class Course
Public Name As String
Public CourseID As String
Public Attendance As List(Of AttendenceRecord)
End Class
And I want a table that looks something like this:
| Course Name | Course ID | [Attendence(0).CourseDate] | [Attendence(1).CourseDate]| ...
| Intro to CS | CS-1000 | 23 | 24 | ...
| Data Struct | CS-2103 | 15 | 14 | ...
How would I, in the general case, get everything to the right of Course ID to be horizontally scrollable, while holding Course Name and Course ID in place? Ideally using a table, listview, or datagrid inside ASP.NET and/or WinForms.
You can get this functionality from the System.Windows.Forms.DataGridView control. When you create columns you can set them to be frozen which will then only scroll those columns to the right of the frozen column(s).
In pure .Net I don't know of anything. There are CSS Solutions for a fixed header. But a fixed left column, in my experience, requires some javascript finangling.
Took me a minute to find the old example. Host has since gone down. http://web.archive.org/web/20080215013647/http://www.litotes.demon.co.uk/example_scripts/tableScroll.html
This is the mechanism I used to get it to work: Take a normal table, and separate it out into 4 other tables. Get the column widths and row heights to match up using business constraints, and then link the onscroll event to scroll the other tables.
Here's an example using just HTML and CSS to achieve what I think you're looking for:
http://www.shrutigupta.com/index.php/2005/12/12/how-to-create-table-with-first-column-frozen/