Всем привет!
Потребовалось в Qt создать класс модели, унаследованный от QAbstractTableModel, модель эта привязана к списку QListView. Проблема возникает при добавлении строк в модель. Если вставлять просто так, то список не обновляется. Если действовать по инструкции, и все операции со вставкой производить между вызовами beginInsertRows() и endInsertRows(), то все строки в списке пропадают, остаётся только свежевставленная. Пробовал вместо этого вызывать reset() после вставки - результат тот же самый.
А как оно вообще должно работать?
Самописная модель в Qt
Модератор: Модераторы разделов
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Самописная модель в Qt
А почему QAbstractTableModel и QListView? Выглядит как-то нелогично.
Наверное, Вы где-то что-то потеряли. Можете привести код, так трудно сказать.
Наверное, Вы где-то что-то потеряли. Можете привести код, так трудно сказать.
-
Obscurus
- Сообщения: 177
Re: Самописная модель в Qt
А почему QAbstractTableModel и QListView?
А есть какая-то принципиальная разница? Вроде бы с QSqlTableModel никаких проблем не было.
Выглядит она примерно так:
Код:
class MyModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit MyModel(QObject *parent = 0);
~MyModel();
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &idx, int role) const;
int addClient(QString client);
private:
QSqlTableModel *model;;
};
MyModel::MyModel(QObject *parent) : QAbstractTableModel(parent) {
model = new QSqlTableModel(this);
model->setTable("clients");
model->select();
}
MyModel::~MyModel() {
delete model;
}
int MyModel::columnCount(const QModelIndex &parent) const {
return 1;
}
int MyModel::rowCount(const QModelIndex &parent) const {
return model->rowCount(parent);
}
QVariant MyModel::data(const QModelIndex &idx, int role) const {
if (role == Qt::DisplayRole) {
if (idx.column() == 0) {
return model->data(model->index(idx.row(), 1), Qt::DisplayRole);
}
}
return QVariant();
}
int MyModel::addClient(QString client) {
model->setFilter(QString("description='%1'").arg(client));
if (model->record(0).field("description").value().toString() == client) return -1;
beginInsertRows(QModelIndex(), 0, 2);
QSqlRecord rec = model->record();
rec.setValue("description", QVariant(client));
model->insertRecord(-1, rec);
endInsertRows();
return 0;
}
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Самописная модель в Qt
Нет, конечно, просто немного странно.
На первый взгляд, всё хорошо. Посмотритекак себя ведёт QSqlTableModel, потому что реализация на QStringList ведёт себя как ожидается:
Код: Выделить всё
class MyTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit MyTableModel(QObject *parent = 0);
signals:
public slots:
// QAbstractItemModel interface
public:
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
public:
void aaa(int row, int count);
private:
QStringList text;
};
MyTableModel::MyTableModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
int MyTableModel::rowCount(const QModelIndex &parent) const
{
return text.size();
}
int MyTableModel::columnCount(const QModelIndex &parent) const
{
return 1;
}
QVariant MyTableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= 0 && index.row() < text.size() && role == Qt::DisplayRole)
return text[index.row()];
return QVariant();
}
void MyTableModel::aaa(int row, int count)
{
beginInsertRows(QModelIndex(), row, row + count - 1);
for (int i = 0; i < count; i++)
text.insert(row + i, QString("Line #%1").arg(text.size()));
endInsertRows();
}-
Obscurus
- Сообщения: 177
Re: Самописная модель в Qt
Причина, как обычно, идиотская: строка
model->setFilter(QString("description='%1'").arg(client));
которая должна была проверять наличие уже внесённой записи фильтрует весь вывод и оставляет только одну строчку.
model->setFilter(QString("description='%1'").arg(client));
которая должна была проверять наличие уже внесённой записи фильтрует весь вывод и оставляет только одну строчку.