PDA

View Full Version : Shopping list type of program: how to move bought items to the bottom of QTreeWidget?



weeezes
27th August 2010, 11:15
Hi!

I'm a beginner with Qt and programming in general, and I'm having a problem with a shopping list type of program I'm trying to do. I have attached a picture to show a bit of what I'm trying to execute..

So I have a QTreeWidget, where I add the items, which are QWidgets. I add them with setCellWidget, when the "Add"-button is clicked. It creates a new widget into the QTreeWidget with the information set below it. I have gotten this to work fine, but I have no idea of the solutions, if there are any, to move the objects that have their checkboxes checked to the bottom of the QTreeWidget.

I assume that I should somehow keep a list of the added items, and their palce in the list. And when the checkbox of an item is clicked, the widget would send a signal that would move the wanted item down and handle the other items and their places accordingly. I don't really have any idea how this could be done, I don't know how new signals and slots are created, even though I have read the documentations and tried to check the examples.

Thank you very much in advance, maybe I could be of help for some newbie in the future, too :)!

tbscope
27th August 2010, 13:18
What you are looking after is sorting.
You want to sort the items in such a way that the unchecked items are on top and the checked items are at the bottom.

Personal opinion:
I don't like it when lists change when I click on an item in the list. I would create two lists. One with all possible items I can buy and one with items I did buy.

Urthas
28th August 2010, 00:57
I don't know how new signals and slots are created

Well, you instantiate a widget that can emit at least one signal (Qt's classes often include one or more signals, which you can find in the class documentation), and then you call QObject::connect() to associate that signal firing with some kind of consequence (usually a function call). Calls to connect() often happen inside a constructor method. A QPushButton quite naturally has a "clicked" signal for example, and we can make use of that signal like this:


QObject::connect(yourButton, SIGNAL(clicked()), someReceiverObject, SLOT(onButtonClicked()));

Now, whenever the button in question is clicked, someReceiverObject's onButtonClicked() function will be called. The onButtonClicked() function is like any other function except that it has been declared as a slot in the appropriate header file:


...
public slots:
void onButtonClicked(); // just an example, doesn't have to be void
...


I suggest reading and re-reading the documentation on signals and slots until you understand most of it. It might take some time to sink in. It might be an idea to hammer away at an introductory text or online tutorial for Object Oriented Programming concepts, too.

weeezes
28th August 2010, 21:02
Thank you to you both :)!

tbscope: I know that I need some kind of sorting, it's just that I don't know how to execute that kind of behaviour in this kind of situation. I bet it needs much work to get this program doing it :S?

Urthas: I know what signals and slots are, and I know how to use them and all that, but I don't know how to create a new signal for an object to emit. I don't remember seeing how to do that in the documentations, and didn't really even find it now when I re-checked them.

I'm really glad for your replies :).

Urthas
29th August 2010, 17:41
I don't know how to create a new signal for an object to emit.

Nothing easier! In your header file, include the following section:



signals:
void yourSignal(); // can also have parameters
...
//rest of class


That's it! (Well ok, they can be declared as protected etc., but that can come later). There is no "definition" of signals in the .cpp file, and their return type must be void. Then, in the .cpp file, you will have the following:



retType yourClass::yourFunction(yourParams)
{
...
emit yourSignal();
...
return ...;
}


The emit statement is often located near or at the end of a function. So now an object of type yourClass will emit yourSignal() whenever yourFunction() is called, and that object can be meaningfully connected to a slot.

Hope this helps!

weeezes
29th August 2010, 20:05
Wow, thank you very much, Urthas! That's exactly what I was strugling to find! That seems so simple that I almost feel embarassed that I ever asked about it :D. The emit statement is a new thing for me, maybe it's a so short word that I have missed it completely :). Let's see if I get something done with this new skill of mine >:)...

Thank you again :).

wysota
29th August 2010, 20:37
What you are looking after is sorting.
You want to sort the items in such a way that the unchecked items are on top and the checked items are at the bottom.
As far as I remember this won't make the cell widgets move as they are not tied to the model in any way :) Unless the Trolls changed this behaviour within the last two years or so...

tbscope
30th August 2010, 05:29
Ohh, I didn't know that.

Sorting would have been the first thing I would try though.

wysota
30th August 2010, 07:51
And I would go for persistant editors instead of cell widgets and moving the items to the bottom of the list manually. Sorting would not be that reliable here as it would be difficult to decide how to order two items with the same check status. Of course such program will only work with lists no longer than about 10 items. For longer ones it'd get very unresponsive due to use of cell widgets or persistant editors.

weeezes
30th August 2010, 17:26
Oh, now I'm confused :). What do you mean by "persistant editors"?

wysota
30th August 2010, 19:31
QAbstractItemView::openPersistentEditor()