C
Qt Quick Ultralite listmodel Example
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
#pragma once
#include "qul/listproperty.h"
#include <qul/model.h>
#include <platforminterface/allocator.h>
#include <string>
#include <limits>
#include <cstdlib>
// To create a custom ListModel<T>, we need to declare a type T that holds
// the data for each element and is equality comparable.
//
// Here, the data type is AlarmData and it holds the number of seconds before
// the alarm should trigger (negative if it has already triggered), as well
// as a running flag.
struct AlarmData
{
AlarmData()
: seconds(0)
, running(false)
{}
AlarmData(int argSeconds, bool argRunning)
: seconds(argSeconds)
, running(argRunning)
{}
int seconds;
bool running;
};
inline bool operator==(const AlarmData &lhs, const AlarmData &rhs)
{
return lhs.seconds == rhs.seconds && lhs.running == rhs.running;
}
// Declare our AlarmModel.
//
// The only requirement is that we implement the pure virtual functions
// count() and data() from ListModel.
//
// We add the other functions to allow our UI to affect the model.
struct AlarmModel : Qul::ListModel<AlarmData>
{
private:
Qul::DynamicList<AlarmData> m_data;
public:
// Implement the ListModel interface
int count() const QUL_DECL_OVERRIDE { return m_data.count(); }
AlarmData data(int index) const QUL_DECL_OVERRIDE { return m_data[index]; }
// Construct the model with some example data.
AlarmModel()
{
m_data.append(AlarmData(-5, false));
m_data.append(AlarmData(11, false));
m_data.append(AlarmData(23, true));
}
// Our app shows a "Pause"/"Unpause" button on each alarm entry.
// This applies the requested state change to the model and then
// informs the view about the change with the dataChanged() call.
void togglePause(int index)
{
m_data.at(index).running = !m_data[index].running;
dataChanged(index);
}
// There is a button to remove an alarm entry. This function removes
// the data for the entry and then calls modelReset() to inform the
// view that the number of entries in the model has changed.
void remove(int index)
{
m_data.removeAt(index);
modelReset();
}
// Adding a new alarm entry is similar to removing one above.
void addEntry(int seconds)
{
m_data.append(AlarmData(seconds, true));
modelReset();
}
// A Timer calls this function on the model every second to update
// the state of the alarms.
void tick()
{
for (int i = 0; i < m_data.count(); ++i) {
AlarmData &entry = m_data.at(i);
if (entry.running || entry.seconds <= 0) {
entry.seconds--;
dataChanged(i);
}
}
}
};