I would like to update weekKm
and weekTime
to update automatically when I change any value in m_weekKmAndTime
, but I am struggling with that. I would like to access it just like DbModel.weekKm(0)
, and have a value, not struggle with vars in QML and trying to get a value there.
.h:
Q_PROPERTY(QVector<QPair<int, int>> weekKmAndTime READ weekKmAndTime NOTIFY weekKmAndTimeChanged)
weekKm and weekTime are Q_INVOKABLE
.cpp:
QVector<QPair<int, int>> DataBaseModel::weekKmAndTime() const
{
return m_weekKmAndTime;
}
int DataBaseModel::weekKm(int day) const
{
return m_weekKmAndTime[day].first;
}
int DataBaseModel::weekTime(int day) const
{
return m_weekKmAndTime[day].second;
}
void DataBaseModel::setWeek(QString day, int new_km, int new_time) {
m_weekKmAndTime[returnNumberFromDay(day)] = qMakePair(new_km, new_time);
qDebug() << new_km << " " << new_time;
emit weekKmAndTimeChanged();
emit weekKmChanged();//this on its own doesn't work
emit weekTimeChanged();
}
Tried to figure out what do you want to achieve. Because I saw that you want to update individual components of the structure, I moved them into a separate class and not messing with QPair. Like this they have their own named properties and their notification signal can be connected to QML. I was lazy with the memory deallocation, so keep in mind that you need to do that.
#ifndef DATABASEMODEL_H
#define DATABASEMODEL_H
#include <QObject>
#include <QVector>
#include <QDebug>
class wkmt : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant km READ km NOTIFY kmChanged)
Q_PROPERTY(int time READ time NOTIFY timeChanged)
public:
explicit wkmt(int km, int time, QObject*parent=nullptr) : mKM{km}, mTime{time}, QObject{parent}
{}
int km() const { return mKM; }
void setKM(int km)
{
if(mKM==km)return;
mKM = km;
emit kmChanged();
}
void setTime(int time)
{
if(mTime==time)return;
mTime = time;
emit timeChanged();
}
int time() const { return mTime; }
signals:
void kmChanged();
void timeChanged();
private:
int mKM;
int mTime;
};
class DataBaseModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QVector<wkmt*> weekKmAndTime READ weekKmAndTime NOTIFY weekKmAndTimeChanged)
public:
explicit DataBaseModel(QObject *parent = nullptr) : QObject{parent}
{
m_weekKmAndTime.push_back(new wkmt(0, 0));
m_weekKmAndTime.push_back(new wkmt(0, 0));
m_weekKmAndTime.push_back(new wkmt(0, 0));
m_weekKmAndTime.push_back(new wkmt(0, 0));
m_weekKmAndTime.push_back(new wkmt(0, 0));
m_weekKmAndTime.push_back(new wkmt(0, 0));
m_weekKmAndTime.push_back(new wkmt(0, 0));
setWeek("Monday", 23, 99);
setWeek("Tuesday", 23, 99);
setWeek("Wednesday", 23, 99);
setWeek("Thursday", 23, 99);
setWeek("Friday", 23, 99);
setWeek("Saturday", 23, 99);
setWeek("Sunday", 23, 99);
}
QVector<wkmt*> weekKmAndTime() const
{
return m_weekKmAndTime;
}
int weekKm(int day) const
{
return m_weekKmAndTime[day]->km();
}
int weekTime(int day) const
{
return m_weekKmAndTime[day]->time();
}
Q_INVOKABLE void setWeek(QString day, int new_km, int new_time) {
m_weekKmAndTime[returnNumberFromDay(day)] = new wkmt(new_km, new_time);
emit weekKmAndTimeChanged();
}
int returnNumberFromDay(const QString& day)
{
QVector<QString> days;
days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday";
return days.indexOf(day);
}
signals:
void weekKmAndTimeChanged();
private:
QVector<wkmt*> m_weekKmAndTime;
};
#endif // DATABASEMODEL_H
QML code:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
width: 640
height: 480
visible: true
Column {
Column {
Repeater {
model: dbModel.weekKmAndTime
delegate: Row {
Text {
text: "km: " + dbModel.weekKmAndTime[index].km
}
Text {
text: ", time: " + dbModel.weekKmAndTime[index].time
}
}
}
}
Button {
text: "Update Tuesday"
onClicked: dbModel.setWeek("Tuesday", 88, 123);
}
}
}
The app looks like this and by pressing the button, it will update the second row (Tuesday)