QAbstractTableModel (помогите разобраться)

Модератор: Модераторы разделов

HoneyDimon
Сообщения: 7
ОС: Win 7

QAbstractTableModel

Сообщение HoneyDimon »

Помогите ламеру понять, почему при создании своего класса и переопределении основных функций просмотр таблици не работает.
А когда базовый класс использую все работает.
Делал все по мануалу.

table.h

Код:

#ifndef TABLE_H #define TABLE_H #include <QAbstractTableModel> #include <QtSql/QSqlTableModel> #include <QtSql> // класс, определяющий модель таблицы class mySqlTableModel : public QAbstractTableModel { Q_OBJECT public: explicit mySqlTableModel(QObject *parent = 0); ~mySqlTableModel(); // переопределяем обязательные функции QVariant data(const QModelIndex &index, int role) const; int rowCount(const QModelIndex &index) const; int columnCount(const QModelIndex &index) const; bool setData(const QModelIndex &index, const QVariant &value, int role); Qt::ItemFlags flags(const QModelIndex &index) const; bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role); private: QSqlTableModel *model; }; #endif // TABLE_H


widget.h

Код:

#ifndef WIDGET_H #define WIDGET_H #include <QWidget> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private: Ui::Widget *ui; }; #endif // WIDGET_H


main.cpp

Код:

#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }


table.cpp

Код:

#include "table.h" #include "widget.h" #include "ui_widget.h" #include <QtSql/QSqlDatabase> #include <QtSql> #include <QSqlError> #include <QSqlRecord> #include <QMessageBox> #include <QtCore> #include <QtGui> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); //Подключаемся к БД MySql QSqlDatabase db; db = QSqlDatabase::addDatabase("QMYSQL"); db.setDatabaseName("ztu"); db.setUserName("root"); db.setHostName("localhost"); db.setPassword("lbvjy@5"); db.open(); mySqlTableModel *mymodel = new mySqlTableModel(this); ui->tableView->setModel(mymodel); QSqlTableModel *a = new QSqlTableModel(this); a->setTable("people"); a->select(); ui->tableView_2->setModel(a); } Widget::~Widget() { delete ui; } mySqlTableModel::mySqlTableModel(QObject *parent): QAbstractTableModel(parent) { model = new QSqlTableModel(this); model->setTable("people"); model->select(); } mySqlTableModel::~mySqlTableModel() { delete model; } QVariant mySqlTableModel::data(const QModelIndex &index, int role) const { if(!index.isValid()) return QVariant(); QVariant value = model->data(index, role); if(role == Qt::DisplayRole) return value; return value; } bool mySqlTableModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) { return model->setHeaderData(section,orientation,value,role); } int mySqlTableModel::rowCount(const QModelIndex &index) const { // qDebug()<< model->rowCount() << "row"; return model->rowCount(index); } int mySqlTableModel::columnCount(const QModelIndex &index) const { // qDebug() << model->columnCount() << "column"; return model->columnCount(index); } bool mySqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { return model->setData(index, value, role); } Qt::ItemFlags mySqlTableModel::flags(const QModelIndex &index) const { return model->flags(index); }


С нижним вфыводом все нормально ( базовый класс),
а с верхним нет работает ( мой класс).

У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: QAbstractTableModel

Сообщение NickLion »

Нужно ещё метод

Код: Выделить всё

QVariant headerData(int section, Qt::Orientation orientation, int role) const;
переопределить для имён колонок.

Почему они у Вас выглядят серыми — не понял. На моём компе выглядит норм. Текущий mySqlTableModel::data и тот, что использовался для запуска точно совпадают? Ничего там не меняли? Ну, и mySqlTableModel::flags тоже. если в этом методе вернуть 0, то ячейки будут неактивными.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: QAbstractTableModel

Сообщение NickLion »

А, понял. У Вас Qt5 используется. В общем, причина в том, что QModelIndex принадлежит Вашей модели, а не модели model. И передавать его туда не совсем верно. Заменить прямую передачу index в model на model->index(index.row(), index.column()), хотя бы в методе flags():

Код: Выделить всё

    return model->flags(model->index(index.row(), index.column()));

И всё станет нормально.
Спасибо сказали:
HoneyDimon
Сообщения: 7
ОС: Win 7

Re: QAbstractTableModel

Сообщение HoneyDimon »

Спасибо, я понял адреса в памяти разные для model и mymodel. Сделал поправку согласно Вашему совету ( заменил везде index на model->index(index.row(),index.column()). Но почемуто не редактируются данные.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: QAbstractTableModel

Сообщение NickLion »

Для редактирования нужно перегрузить ещё методы submit() и revert().

UPD точнее это не для редактирования (оно у Вас есть), а для сохранения изменений.
Спасибо сказали:
HoneyDimon
Сообщения: 7
ОС: Win 7

Re: QAbstractTableModel

Сообщение HoneyDimon »

Да действительно, перегрузил эти функции и все заработало. Спасибо. Странно что в документации про это не сказано. Видимо считается очевидным.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: QAbstractTableModel

Сообщение NickLion »

В описании метода submit() сказано, что используется для отправки закешированных данных в постоянное хранилище. Для реализации не обязательно, если нет постоянного хранилища, наверное поэтому не подчеркнули в общем описании.

Ну, ещё из того, что Вы пропустили — сигналы и слоты. Например: dataChanged(), headerDataChanged(), modelAboutToBeReset(), modelReset(),… QSqlTableModel их отсылает, но в коде они не получены и далее не пересылаются от имени Вашей модели.


И ещё одно, думаю Вы это понимаете, но на всякий случай уточню. Такая модель хороша для понимания, что и как работает. В реальности же, если требуется расширить/изменить поведение QSqlTableModel, следует от него наследоваться и перегрузить только нужные для изменения методы. Меньше работы и правильнее с точки зрения идеологии.
Спасибо сказали: