Qt QTreeWidgetItem - adding children after cleaning old ones - c++

I have a QTreeWidget where upon clicking the expand of an item - when the itemExpanded signal is emitted, I use an algorithm to construct a QList<QTreeWidgetItem*> and add it to the expanded item with QTreeWidgetItem::addChildren.
This works, however if I collapse and expand it again, it adds more children, so I get duplicates. So I have to remove the old children first. For that I use qDeleteAll(item->takeChildren()) and then I add the new ones with addChildren. The thing is, it doesn't work for some reason. It remains empty.
Is there some standart way of performing such an operation?

It sounds like you really want to use a QTreeView with a custom QAbstractItemModel. Yes, that may look a bit scary, if you have never done this before, but the key advantage is that in this approach, the view will ask you for item data, if and when it is needed, without you having to pre-fill it.
Alternatively, do consider the advice given by Michael Boone: Instead of deleting all child items, then re-adding them, why don't you just check whether child items have already been added (optionally updating them, if required)?

Related

Is there a nice way to map a QStandardItemModel to many QLineEdits

I have a single value that needs to appear on several parts of my UI.
Where I have a list of values that is duplicated - for instance QComboboxes, I create a single QStandardItemModel and set that model on the combos.
I'd like to do something similar for this single value. Great, I thought, I'll use QDataWidgetMapper, but it turns out that QDataWidgetMapper doesn't allow one to many mappings, i.e. I can only map one widget to each column in my table. I'd like to map many.
I can think of a few roll-my-own ways around this but if there's an easy way to do it that is built in, I'd appreciate hearing it. I'm on Qt 4.7 fwiw.
You could create a QDataWidgetMapper for each widget.
Alternatively, make one widget be the 'master value' and connect its valueChanged() signal (or whatever you want to call it) to the corresponding setValue() slot of all the 'slave' widgets.

Sitecore Custom Multilist

In Sitecore, I built two custom multi-lists, where the second one depends on the first. The only issue is, that after selecting the first one, I have to save the item before the second multi-list filters the items.
My question somebody know how to create a two custom multi-list on Sitecore, where the second one filters automatically after selecting an item in the first (without save event), or which event can I override to do it?
It sounds like what you are looking for is some kind of front end event that you can use in the Sitecore backend to update a list based on another list selection without a save event. I don't think there is really anything out of the box for that..
Really what you should be doing (to do the 'sitecore' thing) would be to have your first selection (be it multi-list or whatever you like) simply point to a datasource item for another template item which is where your user can set the second option(s). I think you would benefit from taking a different approach like this rather than trying to customise Sitecore here.

Keeping a QLayout sorted

The problem:
I'm creating a class in C++ that contains a QVBoxLayout of buttons that are exclusively checked (clicked). Each button represents a Client object that contains more data than just the title of the button. The new class "SelectionLayout" will emit a signal when any of the buttons are checked and will return an id that can be associated (by the parent class) to the Client object for that button. I want to be able to add and remove buttons from this layout while keeping it sorted by button title. It seems that there is no Qt class or method for inserting a properly sorted widget into a layout, so I have come up with my own solution. I'm a big proponent of doing things the "Standard" way if possible so please let me know if there is a better solution to this problem, or if there is an error in the solution I created. I've googled for quite some time and I'm either missing something very basic, or this is a unique enough problem that everyone is creating their own solution.
My Solution:
Exclusive checking (only one button can be checked at a time) is provided by QButtonGroup, sorting however, is not. So I need an additional data structure to keep it sorted, a Map of (QString, int) seems to make sense here, because it will keep the sorting AND I can associate the checked button to an integer id that will be passed to the parent class. I also need the QVBoxLayout to stay sorted along with the map, which will take some logic of grabbing the index out of the map after inserting and relaying that to the Layout.
The parent class must be able to map the id of each button it creates to the Client object, so that we can properly handle the signal emitted by the SelectionLayout class. I can do this with a QHash (Client*, int) because we don't care about sorting.
All of this seems pretty complicated (Four data structures to hold and keep everything sorted) and I'm hoping there is an easier way.
Thanks in advance for any help, let me know if my explanation isn't adequate.

How to detect dirtyness when removing item from a store?

I have a store with items retrieved from server. I would like to detect changes to alter UI accordingly.
I am able to detect dirty records (new, updated), but I don't know how to detect deletion, which I also need to handle...
An illustration of my problem: http://jsfiddle.net/MikeAski/bBUB2/
Any idea?
There are two things you need to do:
Keep track of what posts were originally there so you can mark it as dirty if one is deleted.
Keep track of new posts, and if they are deleted then mark that part as clean.
Because of your call to each post's isDirty function, you are only checking if the current posts have been updated or created. You basically need a snapshot of what posts exist when it is clean, and then you can compare if any of those have been deleted.
You can also keep a record of newly added posts. That way when one is deleted you can check if it was added(add a isNew flag or something similar). Then when it is deleted you can check if it isNew and mark it clean again otherwise it makes it a dirty delete.
To do these things, you will need a function that checks for deletes as the first dirty check and then check the posts like you currently are.
I finally found a way out: http://jsfiddle.net/MikeAski/bBUB2/7/
This solution is less intrusive on models than the one suggested by jsworkman.
Not fully satisfying, but works as expected... :-/
Still interested in better implementation rather than workaround-flavoured solution!

MFC ctrls and duplicate messages

I have two CListCtrl objects in my form. I want selected list in both of them be same.
How I can do it.
I want duplicate the message that sent to a ClistCtrl and send to other one.
How I can do it?
if this is a good way?
thanks herzl
So, essentially what you're saying is that you want the lists to be synchronized.
You can easily achieve that by adding an event handler to catch the user's selection inside you list control, by adding: ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, OnItemChangedList1) to your dialog/window's message-map.
Inside OnItemChangedList1(), get the index of the currently selected item by calling GetFirstSelectedItemPosition(), and set that as the current index in your second list by calling SetSelectionMark().
This way, whenever the user will click on the 2nd item, for example, in List_A, the 2nd item in List_B will be selected as well.
There ought to be a function that brings that row into view, if it's not in view already, but I can't find it.
I hope that raps it up, ListView's have changed a lot since I've used them, but feel free to ask more if anything is unclear.