Russian Qt Forum
Ноябрь 01, 2024, 04:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Голосование
Вопрос: Что лучше выбрать для больших данных 5000*5000 и все они будут отображатся на таблице?
БД - 6 (33.3%)
QTableWidget - 2 (11.1%)
QAbstractTableModel & QTableView - 10 (55.6%)
другой тип (укажите) - 0 (0%)
Всего голосов: 3

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Для таблицы типа exel, spreadsheet. Помогите новичку.  (Прочитано 17851 раз)
daimon
Гость
« : Декабрь 06, 2009, 14:23 »

Мне нужно создать программу типа exel, spreadsheet
Данных будет очень много 5000*5000 (запас на дурака - данных конечно будет меньше).
Хотелось бы, чтобы оперативы жрал до 200 метров при таком количестве данных (как ексел).
Наверное данные пишутся в файл, а потои подгружаются???
Помогите выбрать тип для таблицы
« Последнее редактирование: Декабрь 06, 2009, 15:25 от daimon » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Декабрь 06, 2009, 23:18 »

Конечно, модель.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
daimon
Гость
« Ответ #2 : Декабрь 06, 2009, 23:33 »

Конечно, модель.
Какой контейнер использовать для данных (2 роли)?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #3 : Декабрь 06, 2009, 23:45 »

Какой контейнер использовать для данных (2 роли)?

QHash
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
daimon
Гость
« Ответ #4 : Декабрь 06, 2009, 23:51 »

Какой контейнер использовать для данных (2 роли)?

QHash
QHash<QPair<int,int>, QVector<QString>>
проблема такого хеша 1500 метров при таблице заполненой 2000*5000
Как можна оптимизировать?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #5 : Декабрь 06, 2009, 23:52 »

QHash<QPair<int,int>, QVector<QString>>

Да, типа того.

BTW: А зачем QVector<QString>?
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #6 : Декабрь 06, 2009, 23:54 »

Как можна оптимизировать?

Добавлять данные в хэш по мере заполнения таблицы. Худший вариант - заполнена вся таблица
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
daimon
Гость
« Ответ #7 : Декабрь 06, 2009, 23:56 »

QHash<QPair<int,int>, QVector<QString>>

Да, типа того.

BTW: А зачем QVector<QString>?
2 роли - 2 элемента вектора (всего я буду использовать только 2 основные роли дисплей и редактиров..)
или вместо вектора QPair<QString,QString>НепонимающийНепонимающий
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #8 : Декабрь 07, 2009, 00:01 »

2 роли - 2 элемента вектора (всего я буду использовать только 2 основные роли дисплей и редактиров..)
или вместо вектора QPair<QString,QString>НепонимающийНепонимающий

А у тебя редактируемые и отображаемые данные будут отличаться?


Код
C++ (Qt)
QHash<QPair<int,int>, QString>

Взгляни хотябы на это:

examples/itemviews/editabletreemodel
« Последнее редактирование: Декабрь 07, 2009, 00:03 от pastor » Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
daimon
Гость
« Ответ #9 : Декабрь 07, 2009, 00:04 »

2 роли - 2 элемента вектора (всего я буду использовать только 2 основные роли дисплей и редактиров..)
или вместо вектора QPair<QString,QString>НепонимающийНепонимающий

А у тебя редактируемые и отображаемые данные будут отличаться?


Код
C++ (Qt)
QHash<QPair<int,int>, QString>
Да будут - в каждой ячейке поработает парсер: ввел 2+2 - получил 4 (видешь в ячейке 4, редактируешь ячейку 2+2)
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #10 : Декабрь 07, 2009, 04:26 »

а я бы всё в одну роль воткнул, только формулу. А считать можно делегата заставить, тогда считать будет только  то, что пользователю показывать надо.

Плюс при раскладе с интами, невозможно будет развивать этот "эксель", например приспичит добавить функцию:
"Сцепить (A1, B1)"
А в каждой из ячеек текст, тогда в результате должен быть тоже текст, но в int его уже не воткнёшь.
« Последнее редактирование: Декабрь 07, 2009, 04:28 от lit-uriy » Записан

Юра.
daimon
Гость
« Ответ #11 : Декабрь 07, 2009, 21:24 »

а я бы всё в одну роль воткнул, только формулу. А считать можно делегата заставить, тогда считать будет только  то, что пользователю показывать надо.

Плюс при раскладе с интами, невозможно будет развивать этот "эксель", например приспичит добавить функцию:
"Сцепить (A1, B1)"
А в каждой из ячеек текст, тогда в результате должен быть тоже текст, но в int его уже не воткнёшь.
Как я понял в примере с редактированым деревом (QT examples): там создается свой класс данных, при добавлении элемента в дерево создается указатель на класс итема.
Понятно, но смутно объясните

Код
C++ (Qt)
#include <QStringList>
 
#include "treeitem.h"
 
//! [0]
TreeItem::TreeItem(const QVector<QVariant> &data, TreeItem *parent)
{
   parentItem = parent;
   itemData = data;
}
//! [0]
 
//! [1]
TreeItem::~TreeItem()
{
   qDeleteAll(childItems);
}
//! [1]
 
//! [2]
TreeItem *TreeItem::child(int number)
{
   return childItems.value(number);
}
//! [2]
 
//! [3]
int TreeItem::childCount() const
{
   return childItems.count();
}
//! [3]
 
//! [4]
int TreeItem::childNumber() const
{
   if (parentItem)
       return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
 
   return 0;
}
//! [4]
 
//! [5]
int TreeItem::columnCount() const
{
   return itemData.count();
}
//! [5]
 
//! [6]
QVariant TreeItem::data(int column) const
{
   return itemData.value(column);
}
//! [6]
 
//! [7]
bool TreeItem::insertChildren(int position, int count, int columns)
{
   if (position < 0 || position > childItems.size())
       return false;
 
   for (int row = 0; row < count; ++row) {
       QVector<QVariant> data(columns);
       TreeItem *item = new TreeItem(data, this);
       childItems.insert(position, item);
   }
 
   return true;
}
//! [7]
 
//! [8]
bool TreeItem::insertColumns(int position, int columns)
{
   if (position < 0 || position > itemData.size())
       return false;
 
   for (int column = 0; column < columns; ++column)
       itemData.insert(position, QVariant());
 
   foreach (TreeItem *child, childItems)
       child->insertColumns(position, columns);
 
   return true;
}
//! [8]
 
//! [9]
TreeItem *TreeItem::parent()
{
   return parentItem;
}
//! [9]
 
//! [10]
bool TreeItem::removeChildren(int position, int count)
{
   if (position < 0 || position + count > childItems.size())
       return false;
 
   for (int row = 0; row < count; ++row)
       delete childItems.takeAt(position);
 
   return true;
}
//! [10]
 
bool TreeItem::removeColumns(int position, int columns)
{
   if (position < 0 || position + columns > itemData.size())
       return false;
 
   for (int column = 0; column < columns; ++column)
       itemData.remove(position);
 
   foreach (TreeItem *child, childItems)
       child->removeColumns(position, columns);
 
   return true;
}
 
//! [11]
bool TreeItem::setData(int column, const QVariant &value)
{
   if (column < 0 || column >= itemData.size())
       return false;
 
   itemData[column] = value;
   return true;
}
//! [11]
 
 
 
 
 
#include <QtGui>
 
#include "treeitem.h"
#include "treemodel.h"
 
//! [0]
TreeModel::TreeModel(const QStringList &headers, const QString &data,
                    QObject *parent)
   : QAbstractItemModel(parent)
{
   QVector<QVariant> rootData;
   foreach (QString header, headers)
       rootData << header;
 
   rootItem = new TreeItem(rootData);
  setupModelData(data.split(QString("\n")), rootItem);
}
//! [0]
 
//! [1]
TreeModel::~TreeModel()
{
   delete rootItem;
}
//! [1]
 
//! [2]
int TreeModel::columnCount(const QModelIndex & /* parent */) const
{
   return rootItem->columnCount();
}
//! [2]
 
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
   if (!index.isValid())
       return QVariant();
 
   if (role != Qt::DisplayRole && role != Qt::EditRole)
       return QVariant();
 
   TreeItem *item = getItem(index);
 
   return item->data(index.column());
}
 
//! [3]
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
   if (!index.isValid())
       return 0;
 
   return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
//! [3]
 
//! [4]
TreeItem *TreeModel::getItem(const QModelIndex &index) const
{
   if (index.isValid()) {
       TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
       if (item) return item;
   }
   return rootItem;
}
//! [4]
 
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
                              int role) const
{
   if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
       return rootItem->data(section);
 
   return QVariant();
}
 
//! [5]
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
{
   if (parent.isValid() && parent.column() != 0)
       return QModelIndex();
//! [5]
 
//! [6]
   TreeItem *parentItem = getItem(parent);
 
   TreeItem *childItem = parentItem->child(row);
   if (childItem)
       return createIndex(row, column, childItem);
   else
       return QModelIndex();
}
//! [6]
 
bool TreeModel::insertColumns(int position, int columns, const QModelIndex &parent)
{
   bool success;
 
   beginInsertColumns(parent, position, position + columns - 1);
   success = rootItem->insertColumns(position, columns);
   endInsertColumns();
 
   return success;
}
 
bool TreeModel::insertRows(int position, int rows, const QModelIndex &parent)
{
   TreeItem *parentItem = getItem(parent);
   bool success;
 
   beginInsertRows(parent, position, position + rows - 1);
   success = parentItem->insertChildren(position, rows, rootItem->columnCount());
   endInsertRows();
 
   return success;
}
 
//! [7]
QModelIndex TreeModel::parent(const QModelIndex &index) const
{
   if (!index.isValid())
       return QModelIndex();
 
   TreeItem *childItem = getItem(index);
   TreeItem *parentItem = childItem->parent();
 
   if (parentItem == rootItem)
       return QModelIndex();
 
   return createIndex(parentItem->childNumber(), 0, parentItem);
}
//! [7]
 
bool TreeModel::removeColumns(int position, int columns, const QModelIndex &parent)
{
   bool success;
 
   beginRemoveColumns(parent, position, position + columns - 1);
   success = rootItem->removeColumns(position, columns);
   endRemoveColumns();
 
   if (rootItem->columnCount() == 0)
       removeRows(0, rowCount());
 
   return success;
}
 
bool TreeModel::removeRows(int position, int rows, const QModelIndex &parent)
{
   TreeItem *parentItem = getItem(parent);
   bool success = true;
 
   beginRemoveRows(parent, position, position + rows - 1);
   success = parentItem->removeChildren(position, rows);
   endRemoveRows();
 
   return success;
}
 
//! [8]
int TreeModel::rowCount(const QModelIndex &parent) const
{
   TreeItem *parentItem = getItem(parent);
 
   return parentItem->childCount();
}
//! [8]
 
bool TreeModel::setData(const QModelIndex &index, const QVariant &value,
                       int role)
{
   if (role != Qt::EditRole)
       return false;
 
   TreeItem *item = getItem(index);
   bool result = item->setData(index.column(), value);
 
   if (result)
       emit dataChanged(index, index);
 
   return result;
}
 
bool TreeModel::setHeaderData(int section, Qt::Orientation orientation,
                             const QVariant &value, int role)
{
   if (role != Qt::EditRole || orientation != Qt::Horizontal)
       return false;
 
   bool result = rootItem->setData(section, value);
 
   if (result)
       emit headerDataChanged(orientation, section, section);
 
   return result;
}
 
void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
{
   QList<TreeItem*> parents;
   QList<int> indentations;
   parents << parent;
   indentations << 0;
 
   int number = 0;
 
   while (number < lines.count()) {
       int position = 0;
       while (position < lines[number].length()) {
           if (lines[number].mid(position, 1) != " ")
               break;
           position++;
       }
 
       QString lineData = lines[number].mid(position).trimmed();
 
       if (!lineData.isEmpty()) {
           // Read the column data from the rest of the line.
           QStringList columnStrings = lineData.split("\t", QString::SkipEmptyParts);
           QVector<QVariant> columnData;
           for (int column = 0; column < columnStrings.count(); ++column)
               columnData << columnStrings[column];
 
           if (position > indentations.last()) {
               // The last child of the current parent is now the new parent
               // unless the current parent has no children.
 
               if (parents.last()->childCount() > 0) {
                   parents << parents.last()->child(parents.last()->childCount()-1);
                   indentations << position;
               }
           } else {
               while (position < indentations.last() && parents.count() > 0) {
                   parents.pop_back();
                   indentations.pop_back();
               }
           }
 
           // Append a new item to the current parent's list of children.
           TreeItem *parent = parents.last();
           parent->insertChildren(parent->childCount(), 1, rootItem->columnCount());
           for (int column = 0; column < columnData.size(); ++column)
               parent->child(parent->childCount() - 1)->setData(column, columnData[column]);
       }
 
       number++;
   }
}
 
 
 
#include <QtGui>
 
#include "mainwindow.h"
#include "treemodel.h"
 
MainWindow::MainWindow(QWidget *parent)
   : QMainWindow(parent)
{
   setupUi(this);
 
   QStringList headers;
   headers << tr("Title") << tr("Description");
 
   QFile file(":/default.txt");
   file.open(QIODevice::ReadOnly);
   TreeModel *model = new TreeModel(headers, file.readAll());
   file.close();
 
   view->setModel(model);
   for (int column = 0; column < model->columnCount(); ++column)
       view->resizeColumnToContents(column);
 
   connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
 
   connect(view->selectionModel(),
           SIGNAL(selectionChanged(const QItemSelection &,
                                   const QItemSelection &)),
           this, SLOT(updateActions()));
 
   connect(actionsMenu, SIGNAL(aboutToShow()), this, SLOT(updateActions()));
   connect(insertRowAction, SIGNAL(triggered()), this, SLOT(insertRow()));
   connect(insertColumnAction, SIGNAL(triggered()), this, SLOT(insertColumn()));
   connect(removeRowAction, SIGNAL(triggered()), this, SLOT(removeRow()));
   connect(removeColumnAction, SIGNAL(triggered()), this, SLOT(removeColumn()));
   connect(insertChildAction, SIGNAL(triggered()), this, SLOT(insertChild()));
 
   updateActions();
}
 
void MainWindow::insertChild()
{
   QModelIndex index = view->selectionModel()->currentIndex();
   QAbstractItemModel *model = view->model();
 
   if (model->columnCount(index) == 0) {
       if (!model->insertColumn(0, index))
           return;
   }
 
   if (!model->insertRow(0, index))
       return;
 
   for (int column = 0; column < model->columnCount(index); ++column) {
       QModelIndex child = model->index(0, column, index);
       model->setData(child, QVariant("[No data]"), Qt::EditRole);
       if (!model->headerData(column, Qt::Horizontal).isValid())
           model->setHeaderData(column, Qt::Horizontal, QVariant("[No header]"),
                                Qt::EditRole);
   }
 
   view->selectionModel()->setCurrentIndex(model->index(0, 0, index),
                                           QItemSelectionModel::ClearAndSelect);
   updateActions();
}
 
bool MainWindow::insertColumn(const QModelIndex &parent)
{
   QAbstractItemModel *model = view->model();
   int column = view->selectionModel()->currentIndex().column();
 
   // Insert a column in the parent item.
   bool changed = model->insertColumn(column + 1, parent);
   if (changed)
       model->setHeaderData(column + 1, Qt::Horizontal, QVariant("[No header]"),
                            Qt::EditRole);
 
   updateActions();
 
   return changed;
}
 
void MainWindow::insertRow()
{
   QModelIndex index = view->selectionModel()->currentIndex();
   QAbstractItemModel *model = view->model();
 
   if (!model->insertRow(index.row()+1, index.parent()))
       return;
 
   updateActions();
 
   for (int column = 0; column < model->columnCount(index.parent()); ++column) {
       QModelIndex child = model->index(index.row()+1, column, index.parent());
       model->setData(child, QVariant("[No data]"), Qt::EditRole);
   }
}
 
bool MainWindow::removeColumn(const QModelIndex &parent)
{
   QAbstractItemModel *model = view->model();
   int column = view->selectionModel()->currentIndex().column();
 
   // Insert columns in each child of the parent item.
   bool changed = model->removeColumn(column, parent);
 
   if (!parent.isValid() && changed)
       updateActions();
 
   return changed;
}
 
void MainWindow::removeRow()
{
   QModelIndex index = view->selectionModel()->currentIndex();
   QAbstractItemModel *model = view->model();
   if (model->removeRow(index.row(), index.parent()))
       updateActions();
}
 
void MainWindow::updateActions()
{
   bool hasSelection = !view->selectionModel()->selection().isEmpty();
   removeRowAction->setEnabled(hasSelection);
   removeColumnAction->setEnabled(hasSelection);
 
   bool hasCurrent = view->selectionModel()->currentIndex().isValid();
   insertRowAction->setEnabled(hasCurrent);
   insertColumnAction->setEnabled(hasCurrent);
 
   if (hasCurrent) {
       view->closePersistentEditor(view->selectionModel()->currentIndex());
 
       int row = view->selectionModel()->currentIndex().row();
       int column = view->selectionModel()->currentIndex().column();
       if (view->selectionModel()->currentIndex().parent().isValid())
           statusBar()->showMessage(tr("Position: (%1,%2)").arg(row).arg(column));
       else
           statusBar()->showMessage(tr("Position: (%1,%2) in top level").arg(row).arg(column));
   }
}
 
 
 
 
#include <QtGui>
 
#include "mainwindow.h"
 
int main(int argc, char *argv[])
{
   Q_INIT_RESOURCE(editabletreemodel);
 
   QApplication app(argc, argv);
   MainWindow window;
   window.show();
   return app.exec();
}
 
 
Пожалуйста особенно функции setData() data()
Вообщем как там хранятся ячейки - про класс итема. Непонимающий
Есть ли в примерах что-нибудь для таблмодела с подобным типом итема? Спасибо заранее.
Помогите переделать этот пример под QAbstractTableModel
« Последнее редактирование: Декабрь 08, 2009, 00:57 от daimon » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #12 : Декабрь 08, 2009, 05:33 »

тебе за каким лешим, дерево, ты с таблицей сначала разберись.
Записан

Юра.
daimon
Гость
« Ответ #13 : Декабрь 09, 2009, 23:56 »

тебе за каким лешим, дерево, ты с таблицей сначала разберись.
Так на примере дерева хочу разобратся с таблицей (интересный создан итем для дерева). Хочу понять как итем работает с деревом. Итем-ячейка в примере или child для parent? child- своя таблица с колонками строками
« Последнее редактирование: Декабрь 10, 2009, 01:26 от daimon » Записан
daimon
Гость
« Ответ #14 : Декабрь 12, 2009, 23:04 »

Код
C++ (Qt)
class Item
{
mutable QString read;
mutable QString edit;
public:
Item()
{
read="";
edit="";
}
Item(QString read_,QString edit_)
{
read=read_;
edit=edit_;
}
void setEdit(QString edit_)
{
edit=edit_;
read=edit+"2";
}
/*void setRead(QString read_)
{
read=read_;
}*/

QString Read() const
{
return read;
}
QString Edit()const
{
 
return edit;
}
};
 
QHash<QPair<unsigned int,unsigned int>,Item> hash_items;

Как лучше считать роль дисплея в setData и записывать в хеш (меняя в классе Item значение read) или  
 или создать QHash<QPair<unsigned int,unsigned int>,QString> hash_items; и вычеслять роль дисплея всегда в data(int role)?

Вычеслять значит - EditRole 2+2 DisplayRole 4 (parser уже есть)
« Последнее редактирование: Декабрь 12, 2009, 23:17 от daimon » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.324 секунд. Запросов: 24.