QTreeView/QAbstractItemModel subtrees in multiple columns - qt

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.

Related

How can I set the values of select lists if one of them is the Parent LOV of the other?

I have two select list : A and B.
A is the parent LOV of B. So when A changes B gets refreshed and changes based on the value of A.
--> B now has lower values to chose from.
Now my problem is that when I select values via PL SQL into the select list (from the database) that select list B never returns the wanted value but the values I would get when I choose the value from A.
--> B should be set to John and A should be set to IT.
--> B returns null value but I can choose all people that work in IT.
When I remove A as Parent LOV then the right value is inserted into B but the list dosent adapt to A.
I use Oracle APEX v.19.1.0.00.15
So I tried it out myself.
I had a button that triggers a Dynamic action. The action was PLSQL code and it just assigned the parent and child. If I set it to assign both of them in the same action, it didnt work, if I separated them out it did.
So change out the actions in your DA(dynamic action) first you have a PLSQL action that assigns the parent item, and you also need to set the Items to return to return this item. Then you have a second action that is the same thing, just for the child.
This works for me, so I am hoping it works for you, let me know if it is still causing you issues

Firebase database: how can I change value of list item?

I have such structure in my database:
User 1
+- items
+- 1
| |- question: some question
| |- answer: some answer
|
+- 2
|- question: another question
I want to add answer to second item, but I don't have the id.
I'm trying to get items and it returns
[null, {answer: some answer, question: some question}, {question: another question}]
But I can't get needed item without answer field and I can't get their ids.
I tried to use equalTo, but it didn't help.
// attempt 1
Query child = _databaseReference.child(item._user).child(db_items).equalTo(null, key: db_answer);
child.reference().once().then((DataSnapshot snapshot) {
print('snapshot: ${snapshot.value}');
});
// attempt 2
Query child = _databaseReference.child(item._user).child(db_items).equalTo(null, key: db_answer);
child.reference().child(db_question).once().then((DataSnapshot snapshot) {
print('snapshot: ${snapshot.value}');
});
First attempt returns the same output as I wrote above, second returns null
So, does anybody know how can I add answer field to second question?
P.S. I use Flutter, but I don't think it means a lot for this issue.
So basically you are trying to add 'answer' to your second item.
I would have done it in this way:
First is to know the key beforehand, so that I can insert a child node in the second item. That way i can write something like:
myDBReference.child("items").child("key_known_beforehand").child("answer").setValue("this is the ansewr");
Or in case I didnt know the key, which seems like the problem here:
I would use Firebase Query. Something like..
myDBReference.child("items").orderByValue().startAt(starting_point_of_child_item).endAt(ending_point_of_child_item).child
This query would givve me the requred node and i would set value there.
"
Using startAt(), endAt(), and equalTo() allows you to choose arbitrary starting and ending points for your queries
To filter data, you can combine any of the limit or range methods with an order-by method when constructing a query.
Unlike the order-by methods, you can combine multiple limit or range functions. For example, you can combine the startAt() and endAt() methods to limit the results to a specified range of values.
"

Function of Rows, Rowsets in PeopleCode

I'm trying to get a better understanding of what Rows and Rowsets are used for in PeopleCode? I've read through PeopleBooks and still don't feel like I have a good understanding. I'm looking to get more understanding of these as it pertains to Application Engine programs. Perhaps walking through an example may help. Here are some specific questions I have:
I understand that Rowsets, Row, Record, and Field are used to access component buffer data, but is this still the case for stand alone Application Engine programs run via Process Scheduler?
What would be the need or advantage to using these as opposed to using SQL objects/functions (CreateSQL, SQLExec, etc...)? I often see in AE programs where the CreateRowset object is instantiated and uses a .Fill method with a SQL WHERE Clause and I don't quite understand why a SQL was not used instead.
I've seen in PeopleBooks that a Row object in a component scroll is a row, how does a component scroll relate to the row? I've seen references to rows having different scroll levels, is this just a way of grouping and nesting related data?
After you have instantiated the CreateRowset object, what are typical uses of it in the program afterwards? How would you perform logic (If, Then, Else, etc..) on data retrieved by the rowset, or use it to update data?
I appreciate any insight you can share.
You can still use Rowsets, Rows, Records and fields in stand alone Application Engines. Application Engines do not have component buffer data as they are not running within the context of a component. Therefore to use these items you need to populate them using built-in methods like .fill() on a rowset, or .selectByKey() on a record.
The advantage of using rowsets over SQL is that it makes the CRUD easier. There are built-in methods for selecting, updating, inserting and deleting. Additionally you don't have to worry about making a large number of variables if there were multiple fields like you would with a SQL object. Another advantage is when you do the fill, the data is read into memory, where if you looped through the SQL, the SQL cursor would be open longer. The rowset, row, record and field objects also have a lot of other useful methods such as allowing you to executeEdits (validation) or copy from one rowset\row\record to another.
This question is a bit less clear to me but I'll try and explain. If you have a Page, it would have a level 0 row. It then could have multiple Level 1 rowsets. Under each of those it could have a level 2 rowsets.
Level0
/ \
Level1 Level1
/ \ / \
Level2 Level2 Level2 Level2
If one of your level1 rows had 3 rows, then you would find 3 rows in the Rowset associated with that level1. Not sure I explained this to answer what you need, please clarify if I can provide more info
Typically after I create a rowset, I would loop through it. Access the record on each row, do some processing with it. In the example below, I look through all locked accounts and prefix their description with LOCKED and then updated the database.
.
Local boolean &updateResult;
local integer &i;
local record &lockedAccount;
Local rowset &lockedAccounts;
&lockedAccounts = CreateRowset(RECORD.PSOPRDEFN);
&lockedAccounts.fill("WHERE acctlock = 1");
for &i = 1 to &lockedAccounts.ActiveRowCount
&lockedAccount = &lockedAccounts(&i).PSOPRDEFN;
if left(&lockedAccount.OPRDEFNDESCR.value,6) <> "LOCKED" then
&lockedAccount.OPRDEFNDESCR.value = "LOCKED " | &lockedAccount.OPRDEFNDESCR.value;
&updateResult = &lockedAccount.update();
if not &updateResult then
/* Error handle failed update */
end-if;
end-if;
End-for;

How to query for existence of child array in Firebase?

Hello Internet Denizens,
I'm using Firebase at the moment and am trying to query the following structure:
items
1
- name: "Car"
- Children
- 2
- 3
2
- name: "Wheels"
3
- name: "Engine"
You can see from this example that I have an array of items with Ids of 1,2, & 3. 1 also has its own sub-array called Children, which is composed of Ids 2 & 3.
How would I make a firebase query that pulled back only the Ids which had an array called children?
At first, I thought something like the following would work:
<my firebase path>.child('items').orderByChild('Children').once('value', function(snap){
// ... No results :(
});
No luck. Next, I tried adding an attribute called hasChildren = true to the Id of 1 and then queried like so.
<my firebase path>.child('items').orderByChild('hasChildren').equalTo(true).once('value', function(snap){
// ... iterate over results, which in this case is the Id 1
});
However, when I do a snap.ForEach(function(data)... and then look at data.val().Children, it's just a blank result, which confuses me because I thought Firebase pulled back all child nodes. Hence, the need to flatten your data.
How do I get those Children values?
** Update ** Plunker Added
http://plnkr.co/edit/9U0ujEwdKi7sgQGmd6IE?p=preview
Looks like this was a comedy of errors.
1) In the simple example, 1, 2, & 3 are ordered, so firebase treats it as an array. In the real world, those numbers are much more random so firebase treats them as an object since they aren't ordered.
2) For some reason, Intellij wasn't showing the Children object's contents. I had to type in something like data.val().Children['3'] to get a value or something like for(var property in data.val().Children) to iterate through the fields. Weird.
3) I STILL can't do .child('items').orderByChild('Children') ... since that returns all records. Oddly enough, however, it returns the ones that have Children first.
DataSnapshot.forEach returns another snapshot in the callback. So instead of trying to access data['Children'], you would have to use data.val().Children.
Looks like modifying my data structure is the best way to go since checking for the existence of an array object isn't possible at this point.

what parameters to be passes to beginInsertRows() when implementing tree.

I have a doubt with canFetch() and fetchMore() functions.
i am implementing tree structure, when i scroll till the end canfetch() will be call and if returns true fetchMore() will be called where we have to fetch the data and insert items into tree.
void model::fetchMore(const QModelIndex& f_parent)
{
//fetch the data needed and create items
beginInsertRows(f_parent, row, lastRow);
endInsertRows();
}
Please let me know In beginInsertRows, what numbers exactly we need to specify, It is confusing me..
I have fetched some data now, in that from top I have 5 child's and followed by 10 parents and each parent has 10 child's. (f_parent parent has 5 childs already)
Now I need to insert 5 more children followed by 10 parents.
now what numbers I need to specify in beginInsertRows() exactly.
beginInsertRows(f_parent,5,f_parent.row()+10); ?
beginInsertRows(f_parent,f_parent.row(),f_parent.row()+10); ?
beginInsertRows(f_parent,5,10); ?

Resources