Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: daimon от Ноябрь 22, 2009, 01:23



Название: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 22, 2009, 01:23
Можна ли заблокировать редактирование для определенной ячейки?


Название: Re: QTableWidget
Отправлено: pastor от Ноябрь 22, 2009, 02:05
см. QTableWidgetItem::setFlags


Название: Re: QTableWidget
Отправлено: daimon от Ноябрь 22, 2009, 18:52
Какое максимальное количество строк, колонок?


Название: Re: QTableWidget
Отправлено: lit-uriy от Ноябрь 22, 2009, 19:09
>>Какое максимальное количество строк, колонок?
А при каком кол-ве у тебя компилятор отказался компилировать? или перестала работать программа?


Название: Re: QTableWidget
Отправлено: daimon от Ноябрь 22, 2009, 19:14
>>Какое максимальное количество строк, колонок?
А при каком кол-ве у тебя компилятор отказался компилировать? или перестала работать программа?
120000000 как обыграть эту ситуацию - ограничение поставить


Название: Re: QTableWidget
Отправлено: spectre71 от Ноябрь 22, 2009, 19:23
>>Какое максимальное количество строк, колонок?
А при каком кол-ве у тебя компилятор отказался компилировать? или перестала работать программа?
120000000 как обыграть эту ситуацию - ограничение поставить

Не использовать QTableWidget!
Использовать Model/View: QAbstractItemView & QAbstractItemModel.
Соответственно в твоем случае: QTableView & QAbstractItemModel или QStandardItemModel


Название: Re: QTableWidget или QAbstractTableMode &QTableView
Отправлено: daimon от Ноябрь 22, 2009, 19:30
>>Какое максимальное количество строк, колонок?
А при каком кол-ве у тебя компилятор отказался компилировать? или перестала работать программа?
120000000 как обыграть эту ситуацию - ограничение поставить

Не использовать QTableWidget!
Использовать Model/View: QAbstractItemView & QAbstractItemModel.
Соответственно в твоем случае: QTableView & QAbstractItemModel или QStandardItemModel
Да но так проблема как представить данные, заголовки.
У меня QTableWidget есть прототип ячейки


Название: Re: QTableWidget или QAbstractTableMode &QTableView
Отправлено: daimon от Ноябрь 22, 2009, 20:42
Как узнать с помощью Qt какой объем оперативной памяти ПК и какую память потребляет приложение?
Если приложение потребляет больше памяти, чем ОЗУ значит добавление колонки (строки) запретить


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 22, 2009, 20:55
>>Если приложение потребляет больше памяти, чем ОЗУ значит добавление колонки (строки) запретить
Несколько непонятное поведение программы.
Положим пользователь располагает 119'999'999 столбцами, затем щёлкает "добавить столбец", а программа ему говорит "Чувак оперативы уже совсем мало!" И как он должен вести себя?

Так же не понятно, как человек будет смотреть такое кол-во столбцов и будет-ли?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 22, 2009, 21:01
>>Если приложение потребляет больше памяти, чем ОЗУ значит добавление колонки (строки) запретить
Несколько непонятное поведение программы.
Положим пользователь располагает 119'999'999 столбцами, затем щёлкает "добавить столбец", а программа ему говорит "Чувак оперативы уже совсем мало!" И как он должен вести себя?

Так же не понятно, как человек будет смотреть такое кол-во столбцов и будет-ли?
Хорошо какой человеческий максимум поставить для колонок и строк?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 22, 2009, 21:09
зависит от размера данных в таблице.
Какие данные ты собираешься предоставлять пользователю?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 22, 2009, 21:12
зависит от размера данных в таблице.
Какие данные ты собираешься предоставлять пользователю?
Таблица для построения графика (таблица может заполнятся цыклом)
Каждая ячейка содержит число (поставлен прототип ячейки)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 22, 2009, 22:04
>>Таблица для построения графика (таблица может заполнятся цыклом)
график, если двумерный - 2 столбца, если графиков несколько то (кол-во+1) столбцов.


>>Каждая ячейка содержит число (поставлен прототип ячейки)
что значит "прототип"?

П.С. правильно "цИкл"



Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 22, 2009, 22:30
>>Таблица для построения графика (таблица может заполнятся циклом)
график, если двумерный - 2 столбца, если графиков несколько то (кол-во+1) столбцов.


>>Каждая ячейка содержит число (поставлен прототип ячейки)
что значит "прототип"?


Написал свой класс наследник QTableWidgetItem, который подсчитывает выражение в ячейке (прототип)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 23, 2009, 00:17
Написал свой класс наследник QTableWidgetItem, который подсчетывает выражение в ячейке (прототип)

Для больших объемов данных(столбцы или колонки ~ > 1000) использовать QTableWidget - бред.
Что делать - уже писал ! - QTableView & QAbstractItemModel

И вообще данный класс(QTableWidget) и сопутствующие ему(QTableWidgetItem...) нужены:
1) Для простого переноса с QT 3(если не ошибаюсь)
2) Для простых и маленьких таблиц - но лучше не использовать
3) Для начинающих программистов



Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 01:53
Для QAbstaractTableModel тогда я должен поставить вектор своих итемов (свой класс наследник QTableWidgetItem),
как элементы модели


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 23, 2009, 02:26
Для QAbstaractTableModel тогда я должен поставить вектор своих итемов (свой класс наследник QTableWidgetItem),
как элементы модели

Нет - ничего подобного!
QTableWidgetItem - здесь совсем ни причем,  он имеет отношение только к QTableWidget.

Изучай "Model/View Programming" в Assistant.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 09:37
QTableWidgetItem наследник какого класса?
Какой контейнер поставить для таблицы 100*100?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 23, 2009, 11:42
QTableWidgetItem наследник какого класса?
Какой контейнер поставить для таблицы 100*100?

Сколько можно повторять - QTableWidgetItem  для своей модели не нужен!
Хранить данные будешь в своем контейнере, а в определенных случаях их можно вообще нигде не хранить - это зависит от источника твоих данных, например в случае если данные генерятся налету.
Если бы ты изучил "Model/View Programming" то таких вопросов бы уже не задавал. Чтение займет час-другой.
Если трудно читать на английском в Assistant, то посмотри здесь:
http://qtdocs.narod.ru/4.1.0/doc/html/model-view-programming.html (http://qtdocs.narod.ru/4.1.0/doc/html/model-view-programming.html)
 


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 21:32
Хорошо, есть класс для одной ячейки (парсит строку и возвращает результат)

Какой контейнер нужно создать для модели таблицы 100*100

(двумерный вектор из моего класса?)
Можете посоветовать!!!!!!!!!!!!!!!
Проблема в том, что в примерах или списки, или пары (а меня может быть как много строк, так и много столбцов)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 23, 2009, 21:53
Хорошо, есть класс для одной ячейки (парсит строку и возвращает результат)

Какой контейнер нужно создать для модели таблицы 100*100

(двумерный вектор из моего класса?)
Можете посоветовать!!!!!!!!!!!!!!!
Проблема в том, что в примерах или списки, или пары (а меня может быть как много строк, так и много столбцов)

Контейнер, а правильнее в данном случае назвать Источник данных не создается для модели! Все наоборот - модель создается для источника данных.
Соответственно , пока ты не описал подробнее свою задачу ничего посоветовать в плане структуры источника нельзя.
- это вполне может быть такой контейнер как двумерный массив
- или вообще без какого-либо контейнера, если данные для ячейки можно получить налету.
простейший пример int getValue(int Col, int Row) {return Col+Row;}

Опиши задачу


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 22:03
Есть таблица, в которую я заношу данные (цифры)
Таблица может менять количество строк и столбцов
Формат записи в таблицу любой (на каждую ячейку поставлен парсер, который возвращает результат выражения в ячейке)
В итоге по этой таблице нужно построит график.

(а так в таблице нужно реализовать сортировку, вставку, копирование....)
Для QTableWidget я всё реализовал , но медленно работает, поставлен прототип для ячейки (парсер)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 23, 2009, 22:05
>>QTableWidgetItem наследник какого класса?
А что мешает посмотреть в Асистенте, в первых строчках указывается базовый класс, если он есть.

>>Какой контейнер нужно создать для модели таблицы 100*100
Смотря что хранить.

>>Если трудно читать на английском в Assistant, то посмотри здесь:
Перевод документации по Qt4 лучше смотреть здесь: http://www.doc.crossplatform.ru.
У А.Корчагина (если не путаю, как зовут), перевод давно не актуализируется. П на кросплатформе содержит и его часть перевода.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 23, 2009, 22:08
>>В итоге по этой таблице нужно построит график.
Вот с этого места по подробнее.
1) человек набивает формулы в таблицу руками?
2) формулы запоминаются, т.е. формулы можно корректировать?
3) Откуда исходные данные, их можно забивать руками?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 22:13
>>В итоге по этой таблице нужно построит график.
Вот с этого места по подробнее.
1) человек набивает формулы в таблицу руками?
2) формулы запоминаются, т.е. формулы можно корректировать?
3) Откуда исходные данные, их можно забивать руками?

есть класс Parser в который я должен отправить строку из любой ячейки. В итоге парсер возвращает число, которое нужно поставить для ячейки (DisplayRole число из парсера, EditRole - введенная строка в ячейку)
Для таких нужд я для QTableWidget реализовал QTableWidgetItem и в эту таблицу заношу как прототип для ячейки.

Код:
class Cell :  public QTableWidgetItem
{


public:
Cell(QStringList names_for_columns_,QString text);
Cell(QStringList names_for_columns__);
~Cell()
{

}


    QTableWidgetItem *clone() const;
    void setData(int role, const QVariant &value);
    QVariant data(int role) const;
    void setFormula(const QString &formula);
    QString formula() const;
    void setDirty();

void set_names_for_columns(QStringList names_for_columns_)
{
names_for_columns =names_for_columns_;
}
// QString text();




private:

    QVariant value() const;
    QVariant evalExpression(const QString &str) const;
   

    mutable QVariant cachedValue;
    mutable bool cacheIsDirty;
mutable QStringList names_for_columns;
mutable parser par;

};


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 23, 2009, 22:22
daimon, по этим трём вопросам ты меня не понял, расскажи, как это выглядит со стороны пользователя.
Какие ему возможности предоставляются.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 22:30
daimon, по этим трём вопросам ты меня не понял, расскажи, как это выглядит со стороны пользователя.
Какие ему возможности предоставляются.
Пользователь создает объект класса QTableWidget и туда заносит итемы setItem(int row,int column ,QString str) переопределил
Каждый итем переопределён под мой класс итема.
При использовании юзер может вводит в таблицу вручную строку или в классе использовать setItem
При работе программы юзер вводит строку (выражение) -> в ячейку ставится посчитаное число, а при редактировании остается введенная пользователем строка (использую роль отображения - число из парсера, роль редактирования - строка пользователя )
Пример spreadsheet Планшета


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 23, 2009, 22:39
daimon, по этим трём вопросам ты меня не понял, расскажи, как это выглядит со стороны пользователя.
Какие ему возможности предоставляются.
Пользователь создает объект класса QTableWidget и туда заносит итемы setItem(int row,int column ,QString str) переопределил
Каждый итем переопределён под мой класс итема.
При использовании юзер может вводит в таблицу вручную строку или в классе использовать setItem
При работе программы юзер вводит строку (выражение) -> в ячейку ставится посчитаное число, а при редактировании остается введенная пользователем строка (использую роль отображения - число из парсера, роль редактирования - строка пользователя )
Пример spreadsheet Планшета


Забудь про  QTableWidgetItem и QTableWidget  !!!!!!!!!!!!!!!!
У тебя что пользователь запускающий твою прогу сам создает объекты классов и вызывает методы, бедный пользователь.

Опиши задачу, а не то как ты себе представляешь отдельные части ее реализации.

1) Что выводится в самом начале(при запуске проги). Есть ли какие-нибудь данные в таблице. Если есть Какие, Сколько, Откуда беруться
2) Далее что можно делать с исходными данными(как это видит пользователь), и подробнее, мы не телепаты.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 22:43
daimon, по этим трём вопросам ты меня не понял, расскажи, как это выглядит со стороны пользователя.
Какие ему возможности предоставляются.
Пользователь создает объект класса QTableWidget и туда заносит итемы setItem(int row,int column ,QString str) переопределил
Каждый итем переопределён под мой класс итема.
При использовании юзер может вводит в таблицу вручную строку или в классе использовать setItem
При работе программы юзер вводит строку (выражение) -> в ячейку ставится посчитаное число, а при редактировании остается введенная пользователем строка (использую роль отображения - число из парсера, роль редактирования - строка пользователя )
Пример spreadsheet Планшета


Забудь про  QTableWidgetItem и QTableWidget  !!!!!!!!!!!!!!!!
У тебя что пользователь запускающий твою прогу сам создает объекты классов и вызывает методы, бедный пользователь.

Опиши задачу, а не то как ты себе представляешь отдельные части ее реализации.

1) Что выводится в самом начале(при запуске проги). Есть ли какие-нибудь данные в таблице. Если есть Какие, Сколько, Откуда беруться
2) Далее что можно делать с исходными данными(как это видит пользователь), и подробнее, мы не телепаты.

Перед тобой таблица 5 колонок 5 строк
Вводишь что тебе надо
В ячейку можешь писать 5+5+5
нажимаешь enter и в ячейке появляется число 15
При нажатии на ячейку с числом 15 для редактирования отображается строка 5+5+5
Выделяешь итемы и после этого строится график
Самый простой вариант для понимания Exel


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 23, 2009, 22:47
Перед тобой таблица 5 колонок 5 строк
Вводишь что тебе надо
В ячейку можешь писать 5+5+5
нажимаешь enter и в ячейке появляется число 15
При нажатии на ячейку с числом 15 для редактирования отображается строка 5+5+5
Выделяешь итемы и после этого строится график
Самый простой вариант для понимания Exel

Уже понятнее. Далее, как таблица может принять очень большие размеры, рассказывай.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 22:48
С помощью диалога задается количество колонок и строк
Есть также диалог заполнения таблицы x от и до  шаг по х
и формула для расчёта


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 23, 2009, 22:56
С помощью диалога задается количество колонок и строк

Это понятно

Есть также диалог заполнения таблицы x от и до  шаг по х
и формула для расчёта

А это не очень.

Это что-то наподобии электронных таблиц, например "Microsoft Excel" ?




Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 23, 2009, 22:58
программу advanced grapher видел, скачай маленькая вот есть то что мне надо


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 23, 2009, 23:20
Я думаю кое-что полезное можно найти в исходниках SciDAVis (http://www.qt-apps.org/content/show.php/SciDAVis?content=63850)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 23, 2009, 23:55
Я думаю кое-что полезное можно найти в исходниках SciDAVis (http://www.qt-apps.org/content/show.php/SciDAVis?content=63850)

Вот тебе простой пример c огромной таблицей 5000000 x 8000000 : :)

.h
Код
C++ (Qt)
class MySrcData  {
 public:
   int myCountRows(void)   {return 5000000;}
   int myCountColumn(void) {return 8000000;}    
   QString getMyDisplayString(int row, int column)  {
     if(row == column) {return QString("Middle");}
     return  QString(QString("Value = ") + QString::number(row+column));
   }
 
};
 
class MyModel : public QAbstractItemModel {
   Q_OBJECT
protected:
  MySrcData* SrcData;
public:
 
 MyModel (MySrcData* Data, QObject *parent = 0);
 virtual ~MyModel ();
 
 virtual QModelIndex parent(const QModelIndex &child) const;
 virtual bool hasChildren(const QModelIndex &parent) const;
 
 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
 virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
 
 virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
 virtual Qt::ItemFlags flags(const QModelIndex &index) const;
};      
 

.cpp
Код
C++ (Qt)
MyModel ::MyModel (MySrcData* Data, QObject *parent)  : QAbstractItemModel (parent)
{
 SrcData = Data;
}
 
MyModel ::~MyModel ()
{
 
}
 
QModelIndex MyModel::parent(const QModelIndex & /*child*/) const {
 return QModelIndex();
}
 
bool MyModel::hasChildren(const QModelIndex &parent) const {
 if (parent.model() == this || !parent.isValid()) {
   return rowCount(parent) > 0 && columnCount(parent) > 0;
 }    
 return false;
}
 
int MyModel::rowCount(const QModelIndex &parent) const {
 if (parent.isValid()) {return 0;}
 return SrcData->myCountRows();
}
 
int MyModel::columnCount(const QModelIndex &parent) const {
 if (parent.isValid()) {return 0;}
 return SrcData->myCountColumn();
}
 
 
QModelIndex MyModel::index(int row, int column, const QModelIndex &parent) const {
 if (parent.isValid())                                   {return QModelIndex();}
 if (row    < 0 || row    >= SrcData->myCountRows())   {return QModelIndex();}
 if (column < 0 || column >= SrcData->myCountColumn()) {return QModelIndex();}
 
 return createIndex(row, column, (void*)NULL);
}                                                
 
 
QVariant MyModel::data(const QModelIndex &index, int role) const {
 if (!index.isValid())                                                  {return QVariant();}
 if (index.row()    < 0 || index.row()    >= SrcData->myCountRows())    {return QVariant();}
 if (index.column() < 0 || index.column() >= SrcData->myCountColumn())  {return QVariant();}
 
 if (role == Qt::DisplayRole)             {
   return SrcData->getMyDisplayString(index.row(), index.column());
 } else if(role == Qt::BackgroundColorRole) {
   if(index.row() == index.column()) {return QVariant();}
   if(index.row() <= index.column()) {return QVariant(QColor(Qt::green));}
   return QVariant(QColor(Qt::yellow));
 }
 
 return QVariant();
}          
 
Qt::ItemFlags MyModel::flags(const QModelIndex &index) const {
 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}              
 

mainwindow конструктор

Код
C++ (Qt)
{
 ui.setupUi(this);
 
 MySrcData* Data = new MySrcData();                    
 MyModel* Model = new MyModel(Data);
 ui.tableView->setModel(Model);
}
 

Не забудь в дизайнере кинуть QTableView на форму!


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 00:35
Я думаю кое-что полезное можно найти в исходниках SciDAVis (http://www.qt-apps.org/content/show.php/SciDAVis?content=63850)

Вот тебе простой пример c огромной таблицей 5000000 x 8000000 : :)

.h
Код
C++ (Qt)
class MySrcData  {
 public:
   int myCountRows(void)   {return 5000000;}
   int myCountColumn(void) {return 8000000;}    
   QString getMyDisplayString(int row, int column)  {
     if(row == column) {return QString("Middle");}
     return  QString(QString("Value = ") + QString::number(row+column));
   }
 
};
 
class MyModel : public QAbstractItemModel {
   Q_OBJECT
protected:
  MySrcData* SrcData;
public:
 
 MyModel (MySrcData* Data, QObject *parent = 0);
 virtual ~MyModel ();
 
 virtual QModelIndex parent(const QModelIndex &child) const;
 virtual bool hasChildren(const QModelIndex &parent) const;
 
 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
 virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
 
 virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
 virtual Qt::ItemFlags flags(const QModelIndex &index) const;
};      
 

.cpp
Код
C++ (Qt)
MyModel ::MyModel (MySrcData* Data, QObject *parent)  : QAbstractItemModel (parent)
{
 SrcData = Data;
}
 
MyModel ::~MyModel ()
{
 
}
 
QModelIndex MyModel::parent(const QModelIndex & /*child*/) const {
 return QModelIndex();
}
 
bool MyModel::hasChildren(const QModelIndex &parent) const {
 if (parent.model() == this || !parent.isValid()) {
   return rowCount(parent) > 0 && columnCount(parent) > 0;
 }    
 return false;
}
 
int MyModel::rowCount(const QModelIndex &parent) const {
 if (parent.isValid()) {return 0;}
 return SrcData->myCountRows();
}
 
int MyModel::columnCount(const QModelIndex &parent) const {
 if (parent.isValid()) {return 0;}
 return SrcData->myCountColumn();
}
 
 
QModelIndex MyModel::index(int row, int column, const QModelIndex &parent) const {
 if (parent.isValid())                                   {return QModelIndex();}
 if (row    < 0 || row    >= SrcData->myCountRows())   {return QModelIndex();}
 if (column < 0 || column >= SrcData->myCountColumn()) {return QModelIndex();}
 
 return createIndex(row, column, (void*)NULL);
}                                                
 
 
QVariant MyModel::data(const QModelIndex &index, int role) const {
 if (!index.isValid())                                                  {return QVariant();}
 if (index.row()    < 0 || index.row()    >= SrcData->myCountRows())    {return QVariant();}
 if (index.column() < 0 || index.column() >= SrcData->myCountColumn())  {return QVariant();}
 
 if (role == Qt::DisplayRole)             {
   return SrcData->getMyDisplayString(index.row(), index.column());
 } else if(role == Qt::BackgroundColorRole) {
   if(index.row() == index.column()) {return QVariant();}
   if(index.row() <= index.column()) {return QVariant(QColor(Qt::green));}
   return QVariant(QColor(Qt::yellow));
 }
 
 return QVariant();
}          
 
Qt::ItemFlags MyModel::flags(const QModelIndex &index) const {
 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}              
 

mainwindow конструктор

Код
C++ (Qt)
{
 ui.setupUi(this);
 
 MySrcData* Data = new MySrcData();                    
 MyModel* Model = new MyModel(Data);
 ui.tableView->setModel(Model);
}
 

Не забудь в дизайнере кинуть QTableView на форму!

За пример большое спасибо!!!!!!!!!!!!!!!!!!!


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 00:44
В модели можна определять функции SetRowCount() SetColumnCount()?
Просто я хочу свой таьлвиджет переписать под модель

Почему при редактировании ячейки почему-то открывается спинбокс QAbstractTableModel?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 24, 2009, 01:55
>>В модели можна определять функции SetRowCount() SetColumnCount()?
какие нужно функции такие и определяй

>>Почему при редактировании ячейки почему-то открывается спинбокс QAbstractTableModel?
Выделенное совершенно не понятно


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 02:00
>>В модели можна определять функции SetRowCount() SetColumnCount()?
какие нужно функции такие и определяй

>>Почему при редактировании ячейки почему-то открывается спинбокс QAbstractTableModel?
Выделенное совершенно не понятно
модель создана на базе QAbstractTableModel


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 24, 2009, 02:01
daimon, с примером  Spectre по осторожнее. там данные не хранятся, они вычисляются в зависимости от индекса строки и столбца


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 24, 2009, 02:01
Почему при редактировании ячейки почему-то открывается спинбокс?

По-умолчанию.
Все что нужно можно сделать! Но надо почитать доку!


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 24, 2009, 02:03
>>модель создана на базе QAbstractTableModel
Если модель создадана на основе "А" это не значит, что спинбокс "А"
Спинбокс к модели вообще никакого отношения не имеет, это просто виджет редактор.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 02:04
#include <QtGui>

// ======================================================================
class TableModel : public QAbstractTableModel {
private:
    int                          m_nRows;
    int                          m_nColumns;
    QHash<QModelIndex, QVariant> m_hash;

public:
    TableModel(int nRows, int nColumns, QObject* pobj = 0)
        : QAbstractTableModel(pobj)
        , m_nRows(nRows)
        , m_nColumns(nColumns)
    {
    }
  
    QVariant data(const QModelIndex& index, int nRole) const
    {
        if (!index.isValid()) {
            return QVariant();
        }
       // QString str =
         //  QString("%1,%2").arg(index.row() + 1).arg(index.column() + 1);
        return (nRole == Qt::DisplayRole || nRole == Qt::EditRole)
               ? m_hash.value(index, QVariant())
               : QVariant();
    }
    
    bool setData(const QModelIndex& index,
                 const QVariant&    value,
                 int                nRole
                )
    {
        if (index.isValid() && nRole == Qt::EditRole) {
            m_hash[index] = value.toString();
            emit dataChanged(index, index);
            return true;
        }
        return false;
    }

    int rowCount(const QModelIndex&) const
    {
        return m_nRows;
    }

    int columnCount(const QModelIndex&) const
    {
        return m_nColumns;
    }

    Qt::ItemFlags flags(const QModelIndex& index) const
    {
        Qt::ItemFlags flags = QAbstractTableModel::flags(index);
        return index.isValid() ? (flags | Qt::ItemIsEditable)
                               : flags;
    }
};

// ----------------------------------------------------------------------
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
QTableView tableView;
   int rows=20000,columns=20000;
   TableModel model(rows, columns);
   for(int i = 0; i < rows; i++)
            for(int j = 0; j < columns; j++)
            {
               QModelIndex index = model.index(i, j);
               model.setData(index, i, Qt::EditRole);
                   tableView.setModel(&model);
    tableView.show();

               app.processEvents();
            }
    

    
    tableView.setModel(&model);
    tableView.show();

    return app.exec();
}

Очень медленно добавляются элементы как исправить?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 02:34
Как реализовать insertColumn(...)
Стандартный вставляет колонку в конец, а мне нужно туда куда указал с помощью параметра


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 24, 2009, 02:43
Ну и начудил!

Добавляем метод:

QString getKey(int row, int column) {
  QString key(QString::number(index.row()));
  key.append(".");
  key.append(QString::number(index.column()));
  return key;
}

Исправляем:

1)
//QHash<QModelIndex, QVariant> m_hash;
QHash<QString, QVariant> m_hash;
2)
//return (nRole == Qt::DisplayRole || nRole == Qt::EditRole)
//               ? m_hash.value(index, QVariant())
//               : QVariant();
if(nRole == Qt::DisplayRole || nRole == Qt::EditRole) {
  QString key(getKey(index.row(), index.column()));
  if(hash.contains(key)) {return m_hash.value(key);}
  else                   {return index.row();}
}
return QVariant();

3)
//m_hash[index] = value.toString();
  QString key(getKey(index.row(), index.column()));
  m_hash[key] = value;

4) Убираем вложенный цикл заполнения
//for(int i = 0; i < rows; i++)
//            for(int j = 0; j < columns; j++)
//            {
//               QModelIndex index = model.index(i, j);
//               model.setData(index, i, Qt::EditRole);
//                   tableView.setModel(&model);
//    tableView.show();
//
//               app.processEvents();
//            }

Теперь храним только то что изменили, а начальный вид идентичен тому что был. И никаких тормозов.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 02:47
Ну и начудил!

Добавляем метод:

QString getKey(int row, int column) {
  QString key(QString::number(index.row()));
  key.append(".");
  key.append(QString::number(index.column()));
  return key;
}

Исправляем:

1)
//QHash<QModelIndex, QVariant> m_hash;
QHash<QString, QVariant> m_hash;
2)
//return (nRole == Qt::DisplayRole || nRole == Qt::EditRole)
//               ? m_hash.value(index, QVariant())
//               : QVariant();
if(nRole == Qt::DisplayRole || nRole == Qt::EditRole) {
  QString key(getKey(index.row(), index.column()));
  if(hash.contains(key)) {return m_hash.value(key);}
  else                   {return index.row();}
}
return QVariant();

3)
//m_hash[index] = value.toString();
  QString key(getKey(index.row(), index.column()));
  m_hash[key] = value.toString();

4) Убираем вложенный цикл заполнения
//for(int i = 0; i < rows; i++)
//            for(int j = 0; j < columns; j++)
//            {
//               QModelIndex index = model.index(i, j);
//               model.setData(index, i, Qt::EditRole);
//                   tableView.setModel(&model);
//    tableView.show();
//
//               app.processEvents();
//            }
А если мне нужно добавлять в цикле элементы, что делать?
И как переписать insertColumn(...)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 24, 2009, 03:05
А если мне нужно добавлять в цикле элементы, что делать?
И как переписать insertColumn(...)
Я уже тебе показал на твоем примере как можно обойти тормоза.
Что ты хочешь добавлять по циклу?
1) Если тебе необходимо увеличить диапазон таблицы:
    m_nRows;
    m_nColumns;
То нужно использовать:
void beginInsertColumns ( const QModelIndex & parent, int first, int last )
void beginInsertRows ( const QModelIndex & parent, int first, int last )
void endInsertColumns ()
void endInsertRows ()
1) Если тебе необходимо уменьшить диапазон таблицы:
    m_nRows;
    m_nColumns;
То нужно использовать:
void beginRemoveColumns ( const QModelIndex & parent, int first, int last )
void beginRemoveRows ( const QModelIndex & parent, int first, int last )
void endRemoveColumns ()
void endRemoveRows ()
2) Если хочешь изменить значения в большом кол-ве ячеек за раз, то зачастую не обязательно заносить их все в hash, возможно можно большую часть вычислять на лету и возвращать вычисленное значение в:
QVariant data(const QModelIndex& index, int nRole) const


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 03:09
А если мне нужно добавлять в цикле элементы, что делать?
И как переписать insertColumn(...)
Я уже тебе показал на твоем примере как можно обойти тормоза.
Что ты хочешь добавлять по циклу?
1) Если тебе необходимо увеличить диапазон таблицы:
    m_nRows;
    m_nColumns;
То нужно использовать:
void beginInsertColumns ( const QModelIndex & parent, int first, int last )
void beginInsertRows ( const QModelIndex & parent, int first, int last )
void endInsertColumns ()
void endInsertRows ()
1) Если тебе необходимо уменьшить диапазон таблицы:
    m_nRows;
    m_nColumns;
То нужно использовать:
void beginRemoveColumns ( const QModelIndex & parent, int first, int last )
void beginRemoveRows ( const QModelIndex & parent, int first, int last )
void endRemoveColumns ()
void endRemoveRows ()
2) Если хочешь изменить значения в большом кол-ве ячеек за раз, то зачастую не обязательно заносить их все в hash, возможно можно большую часть вычислять на лету и возвращать вычисленное значение в:
QVariant data(const QModelIndex& index, int nRole) const

Какой должен быть QModelIndex & parent для того, чтобы  insertColumn(...) работал правильно


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 24, 2009, 03:16
Какой должен быть QModelIndex & parent для того, чтобы  insertColumn(...) работал правильно
Читай доку, не будет таких вопросов.
Я уже устал от них!

В твоем случае(в случае списка или таблицы) parent - пустой, т.е  == QModelIndex().
Не пустой он в случае деревьев.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 03:22
Какой должен быть QModelIndex & parent для того, чтобы  insertColumn(...) работал правильно
Читай доку, не будет таких вопросов.
Я уже устал от них!

В твоем случае(в случае списка или таблицы) parent - пустой, т.е  == QModelIndex().
Не пустой он в случае деревьев.
Где среди библиотек Qt спрятан исходник под абстрактный класс  QAbstracnTableModel - нужна функция insertColumn()
Не могу понять почему эта функция работает неправильно.
Нужно переписать для ёё правильной работы ????????
void beginInsertColumns ( const QModelIndex & parent, int first, int last )
void beginInsertRows ( const QModelIndex & parent, int first, int last )
void endInsertColumns ()
void endInsertRows ()


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 24, 2009, 03:33
daimon, по твоему примеру:
убери tableView.show(); из цикла добавления.
лучше отобрази сначала представление пользователю, а затем начинай добавлять элементы


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 03:34
Будьте добры, ковырялся в исходниках - Qt не могу понять как пашет эта insertColumn(..)
Просветите тёмного


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: lit-uriy от Ноябрь 24, 2009, 06:47
см. подробное описание функции
void QAbstractItemModel::beginInsertColumns ( const QModelIndex & parent, int first, int last )   [protected]

Почитай Создание собственных моделей (http://www.doc.crossplatform.ru/qt/4.4.3/model-view-model-subclassing.html)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 24, 2009, 16:37
daimon, по твоему примеру:
убери tableView.show(); из цикла добавления.
лучше отобрази сначала представление пользователю, а затем начинай добавлять элементы

Сперва прочитай!
http://www.doc.crossplatform.ru/qt/4.4.3/model-view-creating-models.html#an-editable-model (http://www.doc.crossplatform.ru/qt/4.4.3/model-view-creating-models.html#an-editable-model)

И только потом если что не понятно, спрашивай.




Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 22:24
см. подробное описание функции
void QAbstractItemModel::beginInsertColumns ( const QModelIndex & parent, int first, int last )   [protected]

Почитай Создание собственных моделей (http://www.doc.crossplatform.ru/qt/4.4.3/model-view-model-subclassing.html)
Как будет выглядеть реализация этой функции для контейнера  QHash<QModelIndex, QVariant> m_hash (например).
Под колонку нужно оставить место в контейнере?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 24, 2009, 23:10
см. подробное описание функции
void QAbstractItemModel::beginInsertColumns ( const QModelIndex & parent, int first, int last )   [protected]

Почитай Создание собственных моделей (http://www.doc.crossplatform.ru/qt/4.4.3/model-view-model-subclassing.html)
Как будет выглядеть реализация этой функции для контейнера  QHash<QModelIndex, QVariant> m_hash (например).
Под колонку нужно оставить место в контейнере?


Код
C++ (Qt)
bool insertColumns(int startcol, int count, const QModelIndex &parent)  {
    if(startcol!= m_nColumns) {return false;}
    beginInsertColumns(QModelIndex(), startcol, startcol+count-1);
    m_nColumns +=  count;
    endInsertColumns();
    return true;
}

Превая строчка: if(column != m_nColumns) {return false;} - Блокирует вставку колонок внутрь, т.е. данная реализация insertColumns будет позволять только добавлять  колонки в конец!
Чтобы снять ограничение прийдется еще изменять key для сохраненных значений в твоем m_hash у которых column >= startcol

Код
C++ (Qt)
bool insertColumns(int startcol, int count, const QModelIndex &parent)  {
    beginInsertColumns(QModelIndex(), startcol, startcol+count-1);
    if(column != m_nColumns) {changeHashKeysForColumnsMore(startcol, count);}
    m_nColumns +=  count;
    endInsertColumns();
    return true;
}
void changeHashKeysForColumnsMore(int StartColumn, int Offset) {
//...
}
 
 




Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 24, 2009, 23:42
Ну и начудил!

Добавляем метод:

QString getKey(int row, int column) {
  QString key(QString::number(index.row()));
  key.append(".");
  key.append(QString::number(index.column()));
  return key;
}
Вопрос: откуда в этой функции index?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 25, 2009, 00:18
Цитировать
void changeHashKeysForColumnsMore(int StartColumn, int Offset) {
//...
}
Offset за что отвечает?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 25, 2009, 00:32
Ну и начудил!

Добавляем метод:

QString getKey(int row, int column) {
  QString key(QString::number(index.row()));
  key.append(".");
  key.append(QString::number(index.column()));
  return key;
}
Вопрос: откуда в этой функции index?

Оттуда, кусок был перенесен  из другого места.
Если бы ты вообще пытался понять что написано, то заметил бы что это элементарная ошибка  и сам бы исправил.

Код
C++ (Qt)
QString getKey(int row, int column)
 QString key(QString::number(row));  
 key.append(".");
 key.append(QString::number(column));
 return key;
}

А использовать в качестве ключа для hash QModelIndex ("QHash<QModelIndex, QVariant> m_hash;) идея просто бредовая.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 25, 2009, 00:56
Цитировать
void changeHashKeysForColumnsMore(int StartColumn, int Offset) {
//...
}
Offset за что отвечает?
Я должен сместить ключи со значением колонки >= StartColumn на Offset значений вправо

Если Offset=2
StartColumn =1

Все ключи начиная с 1 и до конца всех колонок надо поменять на 3(первая колонка после StartColumn ), 4 (вторая) 5 6 и т.д


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 25, 2009, 01:03
Цитировать
void changeHashKeysForColumnsMore(int StartColumn, int Offset) {
//...
}
Offset за что отвечает?
Я должен сместить ключи со значением колонки >= StartColumn на Offset значений вправо

Если Offset=2
StartColumn =1

Все ключи начиная с 1 и до конца всех колонок надо поменять на 3(первая колонка после StartColumn ), 4 (вторая) 5 6 и т.д


Да. Начиная с col(1)

col(1) -> col(3)
col(2) -> col(4)
...
col(m_nColumns-1) -> col(m_nColumns+1)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 25, 2009, 01:45
Если использовать не хеш, а список скорость и трудоемкость приложения сильно упадёт?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 25, 2009, 09:46
Как можна в хеш-контейнере QHash<QString,QVariant> изменять ключи вставленных элементов без промежуточного элемента?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 25, 2009, 11:21
Как можна в хеш-контейнере QYash<QString,QVariant> изменять ключи вставленных элементов без промежуточного элемента?

Получаем значение по ключу, удаляем, вставляем это значение с другим ключем
===
Вообще то приведенная мной схема чисто для примера. Можно использовать и другие варианты:
- Например взять в качестве ключа QPair ( const T1 & row, const T2 & col )
QHash<QPair<int,int>,QVariant> SrcData;
- Можно также не премещать физически столбцы/строки, а делать переиндексацию - завести например:
QHash<int,int> ColIndex; QHash<int,int> RowIndex; где ключ - VisualIndex(который фактически соответствует визуализации на уровне View), а значение - LogicalIndex(который есть соответствующая часть ключа для SrcData), аналогично тому как сделано в QHeaderView. При этом не обязательно для переиндексации использовать QHash, можно и просто массив int ColIndex[MAX_COL_NUM] если предполагается ограничение на кол-во колонок/строк.
- Можно использовать и другие подходы для оптимизации, все зависит от задачи
===

Тебе так же важно понять что источник данных(Source) и модель(Model) не обязательно одна и та же сущность(объект)!
Model по сути адаптирует или преобразует те или иные запросы к Source. Source нужно строить и оптимизировать с учетом возможных к нему запросов и не только от Model, но и от других сущностей в твоей программе.




Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 26, 2009, 01:22
Правильно было бы проверить в insertColumn(int column)

column>=0&&column<m_nColumns (условие вставки)

m_nColumns - количество всех колонок на данный момент

Правильно?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 26, 2009, 11:03
Правильно было бы проверить в insertColumn(int column)

column>=0&&column<m_nColumns (условие вставки)

m_nColumns - количество всех колонок на данный момент

Правильно?


Тогда скорее column>=0&&column<=m_nColumns


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 26, 2009, 23:38
В removeColumns(int start,int count.....)
нужно делать проверку, чтобы по значениям start и count не выйти за пределы количества колонок


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 27, 2009, 00:17
В removeColumns(int start,int count.....)
нужно делать проверку, чтобы по значениям start и count не выйти за пределы количества колонок

Я проверки делаю всегда.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 28, 2009, 22:29
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
{
   if(role!=Qt::DisplayRole)
   {
      return QVariant();
   }
   return (orientation == Qt::Horizontal) ? QString("ssss"):QString::number(section);
}
списал с книжки
Объясните последнюю строку с помощью if


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Ноябрь 28, 2009, 22:38
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
{
   if(role!=Qt::DisplayRole)
   {
      return QVariant();
   }
   return (orientation == Qt::Horizontal) ? QString("ssss"):QString::number(section);
}
списал с книжки
Объясните последнюю строку с помощью if

А что объяснять - ролей много а мы в данном случае обрабатываем только одну на остальные возвращаем default, т.е. QVariant();
Можно записать и другим образом - обычная логика:

QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
{
    if(role === Qt::DisplayRole) {
        return (orientation == Qt::Horizontal) ? QString("ssss"):QString::number(section);
    } else {
        return QVariant();
    } 
}


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 28, 2009, 23:36
Как обрабатывать выделенные ячейки в модели (selection range)?
Как реализовать функцию получения индекса ячейки, которая есть выделена?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 29, 2009, 00:14
Я хочу реализовать свой QTableWidget только быстрее.
Для этого нужно создать свою модель таблицы; создать класс наследник от своей модели и класса QTableView

Правильно ли я буду делать?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 29, 2009, 21:51
Как реализовать модель для заполнения её данными циклом (таблица 10000*10000)?
QHash<QPair<int,int>,QVariant> просто цикл в лоб занимает очень много времени и 2 гига оперативы.
Как оптимизировать?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Kolobok от Ноябрь 29, 2009, 23:43
Как реализовать модель для заполнения её данными циклом (таблица 10000*10000)?
QHash<QPair<int,int>,QVariant> просто цикл в лоб занимает очень много времени и 2 гига оперативы.
Как оптимизировать?

А что ты хочешь, одни индексы занимают почти 400 MB.

Я бы сделал так:

int rows;
int columns;
QVector< QVariant > data;

data.resize( rows * columns );

А почему QVariant ?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 29, 2009, 23:50
Как реализовать модель для заполнения её данными циклом (таблица 10000*10000)?
QHash<QPair<int,int>,QVariant> просто цикл в лоб занимает очень много времени и 2 гига оперативы.
Как оптимизировать?

А что ты хочешь, одни индексы занимают почти 400 MB.

Я бы сделал так:

int rows;
int columns;
QVector< QVariant > data;

data.resize( rows * columns );

А почему QVariant ?
Хочется сделать универсальную таблицу (хочу потом добавить итемы чекбоксы)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 30, 2009, 00:02
с вектором проблематично переписать такой код и вектор будет содержать несколько миллионов значений
   void Table_model::changeHashColumns(int StartColumn, int Offset, bool insert_remove)
   {
      int i=0;
      
       for (int row = 0; row < numRows; ++row)
       {
         //if(Offset==numColumns)
         //   i=numColumns;
         //else i=numColumns-Offset;
         for( i=numColumns-1;i>=StartColumn; i--)
         {
            if(!hash_items.value(QPair<int,int> (row,i)).isNull())
            {
               if(insert_remove==true) hash_items[QPair<int,int> (row,i+Offset)]=hash_items[QPair<int,int> (row,i)];
               hash_items.remove(QPair<int,int> (row,i));
            }
         }

      }
   }

   //------------insert column
    bool Table_model::insertColumns(int startcol, int count, const QModelIndex &parent) 
    {
      
       if(startcol>=0 && startcol<=numColumns&& count>=1)
       {      
          beginInsertColumns(QModelIndex(), startcol, startcol+count-1);
         if(startcol <= numColumns) {changeHashColumns(startcol, count,true);}
         //numColumns +=  count;
   for(int i=0;i<count;i++)
   {
      
      names_for_columns.insert(startcol+i,for_column_name_from_number(numColumns));
      numColumns ++;
   }

      //setHorizontalHeaderLabels(names_for_columns);
      
      /*
      
      if(number_column_into_paste==0)
          setCurrentCell(0,number_column_into_paste);
      else
          setCurrentCell(0,number_column_into_paste-1);*/

         endInsertColumns();
         return true;
        }
       else false;
   }
   
    void Table_model::insertColumn(int column, const QModelIndex &parent)
    {
       if(column>=0 && column<=numColumns)
       insertColumns(column,1,parent);
    }
помогите переписать код для вектора проблема в insert columns ->  changeHashColumns


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 30, 2009, 00:31
вектор размером(10000*10000) не создается, а хеш да


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 30, 2009, 00:50
Как реализовать модель для заполнения её данными циклом (таблица 10000*10000)?
QHash<QPair<int,int>,QVariant> просто цикл в лоб занимает очень много времени и 2 гига оперативы.
Как оптимизировать?

А что ты хочешь, одни индексы занимают почти 400 MB.

Я бы сделал так:

int rows;
int columns;
QVector< QVariant > data;

data.resize( rows * columns );

А почему QVariant ?
А может QHash<int,QVariant>


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 30, 2009, 22:09
или лучше использовать А может QHash<int,QVariant*>


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Igors от Ноябрь 30, 2009, 22:20
вектор размером(10000*10000) не создается, а хеш да
Когда таблица пустая - да, создается. А когда начнет заполняться - hash съест больше чем вектор. И что тогда будете делать?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 30, 2009, 22:30
вектор размером(10000*10000) не создается, а хеш да
Когда таблица пустая - да, создается. А когда начнет заполняться - hash съест больше чем вектор. И что тогда будете делать?
с вектором проблема для функций вставки колонки, где нужно менять индексы для элементов (для этого нужно резервировать место полностью под вектор). Но так как индекс это порядковый номер в таблице - нужно перебрать весь вектор, а в хеше удаляешь старый элемент с ключом и ставишь новый


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Ноябрь 30, 2009, 22:35
struct Data
{
   QVariant a;
  int row;
  int column;
}
QVector<Data> f;

такой вектор будет жрать меньше, чем QHash<QPair<int,int>,QVariant>


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Igors от Декабрь 01, 2009, 11:30
с вектором проблема для функций вставки колонки, где нужно менять индексы для элементов (для этого нужно резервировать место полностью под вектор). Но так как индекс это порядковый номер в таблице - нужно перебрать весь вектор, а в хеше удаляешь старый элемент с ключом и ставишь новый
Не путайте "мне меньше писать" с "производительностью", удаление/вставка в hash много чего делает каждая. Не храните индексы (row, column) для каждого элемента ни в каком виде - это никак Вам не поможет выкрутиться с памятью. Используйте простую и естественную модель, вариантов много

QVector <QVariant>          // съест меньше всех памяти но нужно пересоздавать при вставке/удалении
QList <QList<QVariant>>   //  съест чуть больше памяти но легко удалять/вставлять
QVector <QVector<QVariant>>   // промежуточный
и.т.п.

Умерьте Ваши притязания на "очень большую таблицу" - до этого еще дожить надо


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: spectre71 от Декабрь 01, 2009, 11:56
с вектором проблема для функций вставки колонки, где нужно менять индексы для элементов (для этого нужно резервировать место полностью под вектор). Но так как индекс это порядковый номер в таблице - нужно перебрать весь вектор, а в хеше удаляешь старый элемент с ключом и ставишь новый
Не путайте "мне меньше писать" с "производительностью", удаление/вставка в hash много чего делает каждая. Не храните индексы (row, column) для каждого элемента ни в каком виде - это никак Вам не поможет выкрутиться с памятью. Используйте простую и естественную модель, вариантов много

QVector <QVariant>          // съест меньше всех памяти но нужно пересоздавать при вставке/удалении
QList <QList<QVariant>>   //  съест чуть больше памяти но легко удалять/вставлять
QVector <QVector<QVariant>>   // промежуточный
и.т.п.

Умерьте Ваши притязания на "очень большую таблицу" - до этого еще дожить надо

Я об этом уже писал выше.
Приводил вариант как это можно очень просто сделать!

- Можно также не премещать физически столбцы/строки, а делать переиндексацию - завести например:
QHash<int,int> ColIndex; QHash<int,int> RowIndex; где ключ - VisualIndex(который фактически соответствует визуализации на уровне View), а значение - LogicalIndex(который есть соответствующая часть ключа для SrcData), аналогично тому как сделано в QHeaderView. При этом не обязательно для переиндексации использовать QHash, можно и просто массив int ColIndex[MAX_COL_NUM] если предполагается ограничение на кол-во колонок/строк.
- Можно использовать и другие подходы для оптимизации, все зависит от задачи

Безполезно что-либо объяснять, только трата времени. Человек не читает и не пытается понять. Все время возвращается к своей начальной идее выделеить кучу памяти под все.



Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Декабрь 01, 2009, 23:41
А если создать QList<QList<QVariant*>>
Заполнять такой список полностью построчно (таблица 100*100 - в списке 10000 элементов)
Все не заполненные ячейки таблицы (пользователем)- пустые указатели.
Такой вариант убъет память на таблице 5000*5000

Преимущество такого варианта над хешом 100 метров на 5000*2000
а времени переписать код мало


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Igors от Декабрь 02, 2009, 13:10
А если создать QList<QList<QVariant*>>
Заполнять такой список полностью построчно (таблица 100*100 - в списке 10000 элементов)
Все не заполненные ячейки таблицы (пользователем)- пустые указатели.
Такой вариант убъет память на таблице 5000*5000

Преимущество такого варианта над хешом 100 метров на 5000*2000
Не вижу ничего плохого в такой модели

а времени переписать код мало
Да Вы на форуме уже раз в 10 больше времени потеряли :) Перепишите за час на новую модель - и дело с концом


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Декабрь 03, 2009, 00:28
Как делать resize для списка QList<QList<QVariant*>>, чтобы не делать ресайз каждой строки списка в цикле?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Igors от Декабрь 03, 2009, 13:42
Как делать resize для списка QList<QList<QVariant*>>, чтобы не делать ресайз каждой строки списка в цикле?
QList не имеет resize - но он Вам и не нужен. Используйте insert в цикле для вставки столбцов и erase для их удаления. 


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Декабрь 03, 2009, 21:07
Как делать resize для списка QList<QList<QVariant*>>, чтобы не делать ресайз каждой строки списка в цикле?
QList не имеет resize - но он Вам и не нужен. Используйте insert в цикле для вставки столбцов и erase для их удаления. 
Тогда список не подойдет как контейнер (как тогда узнать индекс) - лучше вектор (индекс ячейки оператор [])


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Igors от Декабрь 03, 2009, 21:11
Тогда список не подойдет как контейнер (как тогда узнать индекс) - лучше вектор (индекс ячейки оператор [])
QList - это тоже массив (не смущайтесь что list это "список") он имеет оператор [] так же как и QVector.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Декабрь 03, 2009, 21:48
Тогда список не подойдет как контейнер (как тогда узнать индекс) - лучше вектор (индекс ячейки оператор [])
QList - это тоже массив (не смущайтесь что list это "список") он имеет оператор [] так же как и QVector.
Нет просто для индексации всей таблицы нужен вектор (ячейка может быть только в последней колонке, индекс [])
Например 2 колонка 2 строка - [2][2], а если insert то индекс уже не будет такой (вектор изменяется под размер таблицы)
Размер вектора может быть 2000*2000 и содержит всего один элемент [2][2]


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Igors от Декабрь 03, 2009, 22:10
Тогда список не подойдет как контейнер (как тогда узнать индекс) - лучше вектор (индекс ячейки оператор [])
QList - это тоже массив (не смущайтесь что list это "список") он имеет оператор [] так же как и QVector.
Нет просто для индексации всей таблицы нужен вектор (ячейка может быть только в последней колонке, индекс [])
Например 2 колонка 2 строка - [2][2], а если insert то индекс уже не будет такой (вектор изменяется под размер таблицы)
Размер вектора может быть 2000*2000 и содержит всего один элемент [2][2]
Возможно Вы хотите сказать что будете хранить вектор указателей из 2000*2000 элементов но только один элемент указывает на данные (остальные NULL). По поводу insert: да, когда Вы вставляете новую колонку - индексы изменятся, но ведь это нормально, так и должно быть. Если же Вы имеете ввиду что-то другое - поясните, лучше на примере.


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Декабрь 03, 2009, 22:42
Тогда список не подойдет как контейнер (как тогда узнать индекс) - лучше вектор (индекс ячейки оператор [])
QList - это тоже массив (не смущайтесь что list это "список") он имеет оператор [] так же как и QVector.
Нет просто для индексации всей таблицы нужен вектор (ячейка может быть только в последней колонке, индекс [])
Например 2 колонка 2 строка - [2][2], а если insert то индекс уже не будет такой (вектор изменяется под размер таблицы)
Размер вектора может быть 2000*2000 и содержит всего один элемент [2][2]
Возможно Вы хотите сказать что будете хранить вектор указателей из 2000*2000 элементов но только один элемент указывает на данные (остальные NULL). По поводу insert: да, когда Вы вставляете новую колонку - индексы изменятся, но ведь это нормально, так и должно быть. Если же Вы имеете ввиду что-то другое - поясните, лучше на примере.
QList не подходит, лучше QVector. Как делать resize для вектора QVector<QVector<QVariant*>>, чтобы не делать ресайз каждой строки вектора в цикле?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Kolobok от Декабрь 04, 2009, 02:08
Сколько всего реальных данных предполагается хранить в таблице?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: Igors от Декабрь 04, 2009, 14:41
QList не подходит, лучше QVector. Как делать resize для вектора QVector<QVector<QVariant*>>, чтобы не делать ресайз каждой строки вектора в цикле?
Если надо вставить колонку (не строку) - то ресайз в цикле делать придется, какой бы контейнер Вы ни взяли (любой из Qt, любой из STL). Непонятно чем Вам не угодил удобный QList и какую задачу Вы решаете :)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: MoPDoBoPoT от Декабрь 04, 2009, 16:30
Только если не считать, что мы храним вектор со столбцами, но тогда добавить строку - борода  :)


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Декабрь 04, 2009, 21:47
Только если не считать, что мы храним вектор со столбцами, но тогда добавить строку - борода  :)
Если использовать SQL не будет проблема с памятью для очень больших таблиц?


Название: Re: QTableWidget или QAbstractTableModel &QTableView
Отправлено: daimon от Декабрь 04, 2009, 22:06
Как организовать свой контейнер, чтобы таблица позволяла использовать роли (Qt::Disp....Qt::Edit)?