π Quick Start With C++
Most of the time you want to store more than just QObject
type, so create your custom type.
class Foo : public QObject
{
Q_OBJECT
public:
Foo(QObject* parent = nullptr) : QObject(parent) {}
int foo = 0;
};
Then use a QOlm
based object with class inheritance or as a typedef.
#include <Foo.hpp>
#include <QOlm/QOlm.hpp>
// Declare type
using FooList = qolm::QOlm<Foo>;
// Or create custom class
class FooList : public qolm::QOlm<Foo>
{
Q_OBJECT
public:
Foo(QObject* parent = nullptr,
const QList<QByteArray> & exposedRoles = {},
const QByteArray & displayRole = {}):
qolm::QOlm<Foo>::(parent, exposedRoles, displayRole)
{
}
};
Then simply use it as a regular list.
π Api
Insert elements
The object provide multiple way to insert an object in the list:
append
: Add an object at the end of the list.prepend
: Add an object at the beginning of the list.insert
: Insert object at requested offset.
Those three functions can also take a QList<_Object*>
as a parameter entry to insert multiple object at once.
FooList list;
Foo foo1;
Foo foo2;
Foo foo3;
Foo foo4;
// {foo1}
list.append(&foo1);
// {foo2, foo1}
list.prepend(&foo2);
// {foo2, foo1, foo3}
list.append(&foo3);
// {foo2, foo4, foo1, foo3}
list.insert(1, &foo4);
Remove elements
To remove an item, simply call the remove
function, either with a pointer to the _Object*
, or with the index of the object at which you want to remove.
All elements can also be removed using clear
function.
FooList list;
Foo foo1;
Foo foo2;
Foo foo3;
Foo foo4;
list.append({&foo1, &foo2, &foo3, &foo4});
// { &foo1, &foo2, &foo4 }
list.remove(&foo3);
// { &foo1, &foo2 }
list.remove(2);
// Remove all elements.
list.clear();
Move elements
Elements can be moved within the list, without changing the list size.
move
from object at indexfrom
to indexto
.moveUp
: Move object at indexindex
toindex-1
. This function make sense when seeing the list in aListView
for example. It move the item to previous index.moveDown
: Move object fromindex
toindex+1
. This function make sense in aListView
in a column. It move the item to next index.moveNext
: alias ofmoveDown
.movePrevious
: alias ofmoveUp
.
FooList list;
Foo foo1;
Foo foo2;
Foo foo3;
Foo foo4;
list.append({&foo1, &foo2, &foo3, &foo4});
// { &foo1, &foo3, &foo4, &foo2 }
list.move(1, 3);
// { &foo2, &foo1, &foo3, &foo4 }
list.move(3, 0);
// { &foo2, &foo3, &foo1, &foo4 }
list.movePrevious(2);
// { &foo2, &foo3, &foo4, &foo1 }
list.moveNext(2);
Access element and get index
Multiple accessors can be used to get data.
get
: Get pointer to the_Object*
atindex
.indexOf
: Get theindex
from a_Object*
contains
: Get if a_Object*
is present.size
: Give the number of objects in the modelempty
: True if model is empty.
π Object ownership
The library follow qt ownership rules. So when inserting an object without parent, the list take ownership of that object. When the same object is removed it will be deleteLater
.
FooList list;
// list take ownership on new Foo
list.append(new Foo());
// Since FooList have ownership on the foo at index 0, it call deleteLater on it. No need to worry about memory management.
list.remove(0);
π Observe Insert/Remove/Move
Observe as QAbstractItemModel
The qolm::QOlm
derived object can be observe for insertion and deletion like any qt model.
But those signals are not very convenient to use as a end user. Thatβs why QOlm
provide other way to observe the list.
Observe thru signals
qolm::QOlmBase
provide basic signal to react to QObject
insert/remove/move operation.
onObjectInserted(QObject* object, int index)
onObjectRemoved(QObject* object, int index)
onObjectMoved(QObject* object, int from, int to)
They are call when the model can safely be iterated. You can simply retrieve a correct pointer by using qobject_cast<_Object*>(object)
.
Function override observe.
Sometime it can be useful to do some processing before the whole world gets notify about our object operation. This method is only available if you define a custom list type.
#include <Foo.hpp>
#include <QOlm/QOlm.hpp>
class FooList : public qolm::QOlm<Foo>
{
Q_OBJECT
public:
FooList(QObject* parent = nullptr,
const QList<QByteArray> & exposedRoles = {},
const QByteArray & displayRole = {}):
QOlm<Foo>(parent, exposedRoles, displayRole)
{
}
protected:
void onObjectAboutToBeInserted(_Object* item, int row) override
{
// Object is not yet inserted, do some preinsert operation on it.
}
void onObjectInserted(_Object* item, int row) override
{
// Object just got inserted, but no callback/signal have been called yet.
}
void onObjectAboutToBeMoved(_Object* item, int src, int dest) override
{
// Object haven't move yet, and no callback/signal have been called yet
}
void onObjectMoved(_Object* item, int src, int dest) override
{
// Object have been moved. No Callback/Signal have been called yet.
}
void onObjectAboutToBeRemoved(_Object* item, int row) override
{
// Object isn't removed yet, and no callback/signal have been called yet
}
void onObjectRemoved(_Object* item, int row) override
{
// Object have been removed. Callback/Signal have been called
}
};
Observe with callback
Regular callback not dependent on qt can be used to handle insert/remove/move operation. We canβt use signal with correct pointer type because qt doesnβt support template moc.
FooList list;
list.onInserted([](const InsertedCallbackArgs& foo)
{
// foo->foo can be directly accessed
// foo.object gives a _Object*
// foo.index gives inserted object index
});
list.onRemoved([](const RemovedCallbackArgs& foo)
{
// foo->foo can be directly accessed
// foo.object gives a _Object*
// foo.index gives removed object index
});
list.onMoved([](const MovedCallbackArgs& foo)
{
// foo->foo can be directly accessed
// foo.object gives a _Object*
// foo.from gives previous object index
// foo.to gives new object index
});
Benefit of this method, is that the list can be observed by non qt object.
Each function return a callback handle that can be used to remove the callback.
auto handleInsert = list.onInserted([](const InsertedCallbackArgs& foo) {});
list.stopListenInsert(handleInsert);
auto handleRemove = list.onInserted([](const InsertedCallbackArgs& foo) {});
list.stopListenRemove(handleRemove);
auto handleMove = list.onInserted([](const InsertedCallbackArgs& foo) {});
list.stopListenMove(handleMove);
Iterator
QOlm
is compatible with modern iterator, you can simply do:
FooList list;
for(const auto foo : list)
{
//foo->getFoo()
}