Я новичок в Qt Model/View Framework. У меня возникли проблемы с использованием подкласса QAbstractTableModel (MyModel) с QTableView. После создания объекта MyModel я хочу установить для него 2 строки и 2 столбца. У меня есть функция инициализации, которая устанавливает все переменные класса и затем испускает СИГНАЛ dataChanged(), но все же представление ничего не показывает.
class MyModel : QAbstractTableModel
{
public:
MyModel();
Initialise(double **a, int r, int c);
private:
int row;
int column;
double **array;
}
MyModel::Initialise(double **a, int r, int c)
{
array = a;
row = r;
column = c;
emit dataChanged(index(0, 0), index(r - 1, c - 1));
}
Я повторно выполнил все необходимые функции для доступа только для чтения. Но все же я получаю пустое окно. Создал вышеуказанный код в Блокноте для иллюстрации, поэтому, пожалуйста, игнорируйте синтаксические ошибки. Я не смог найти какой-либо пример в Qt SDK для создания пользовательской модели из QAbstractTableModel. Поэтому, пожалуйста, дайте мне знать, каков правильный метод инициализации данных в модели.
РЕДАКТИРОВАТЬ:
QVariant TableModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid())
return QVariant();//currently it is returning from here, why???
switch(role)
{
case Qt::DisplayRole:
{
if(index.column()==0)
return QString::number(array[index.row()][index.column()]);
break;
}
}
}
Сигнал dataChanged
заставляет просмотр обновлять существующие элементы. Он не говорит, что количество строк или столбцов изменилось. layoutChanged
этого следует использовать layoutAboutToBeChanged
и layoutChanged
. Вы можете использовать их без каких-либо параметров.
Убедитесь, что вы rowCount
columnCount
виртуальные функции rowCount
и columnCount
.
Я не знаю, почему index.isValid()
является ложным в вашей функции. Проверьте свойства index model()
, row()
и column()
чтобы выяснить, почему именно это недопустимо. Как правило, для представления можно вызвать функции data
с произвольными аргументами. Поскольку ваш взгляд предполагает, что ваша модель пуста, все индексы, скорее всего, недействительны. Когда вы увидите любые строки и столбцы в представлении, вы начнете получать действительные индексы.
Также, если инициализация выполняется только один раз, лучше сделать это, прежде чем назначать модель виду.
И не используйте double**
. Вместо этого используйте автоматическое управление памятью (например, QVector
). В конце концов, это C++.
Для инициализации данных в таблице необходимо переопределить функцию данных, rowCount и clumnCount вместе с конструктором модели. предположим, что у вас есть данные int mydataarray [r] [c], которые инициализируются в конструкторе.
TableModel::TableModel(int r,int c, double **initialdata)
{
R = r;
C = c;
mydataarray= initialdata;
}
QVariant TableModel::data(const QModelIndex &index, int role) const
{
switch(role)
{
case Qt::DisplayRole:
if(index.column()==0)
{
return QString::number(maydataarray[index.row()][index.column()]);
}
break;
}
Чтобы установить количество строк и столбцов, переопределите
int TableModel::rowCount(const QModelIndex &parent= QModelIndex()) const
{
return R;//R is number of initial rows
}
int TableModel::columnCount(const QModelIndex &parent= QModelIndex()) const
{
return C;//C is number of initial columns
}
в функции инициализации, которую вы можете использовать для изменения, но вам нужно вставлять строки и столбцы в модель, если они превышают начальные значения r и c
void TableModel::Initialize(double **a, int r, int c)
{
QModelIndex m = createIndex(0,0);
if(r>this->rowCount(m)||c>this->columnCount(m))
{
QMessageBox m1;
m1.setText("Exciding r/c "+ QString::number(m.row())+QString::number(m.column()));
m1.exec();
return;//add logic to insert exceeding rows and columns here before calling dataChange() function
}
mydataarray =a;
QModelIndex n = createIndex(r-1,c-1);
this->dataChanged(createIndex(0,0),n);
}
см. это для дальнейшего