Название: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 06, 2009, 14:23
Мне нужно создать программу типа exel, spreadsheet Данных будет очень много 5000*5000 (запас на дурака - данных конечно будет меньше). Хотелось бы, чтобы оперативы жрал до 200 метров при таком количестве данных (как ексел). Наверное данные пишутся в файл, а потои подгружаются??? Помогите выбрать тип для таблицы
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: Пантер от Декабрь 06, 2009, 23:18
Конечно, модель.
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 06, 2009, 23:33
Конечно, модель.
Какой контейнер использовать для данных (2 роли)?
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: pastor от Декабрь 06, 2009, 23:45
Какой контейнер использовать для данных (2 роли)?
QHash
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 06, 2009, 23:51
Какой контейнер использовать для данных (2 роли)?
QHash QHash<QPair<int,int>, QVector<QString>> проблема такого хеша 1500 метров при таблице заполненой 2000*5000 Как можна оптимизировать?
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: pastor от Декабрь 06, 2009, 23:52
QHash<QPair<int,int>, QVector<QString>>
Да, типа того. BTW: А зачем QVector<QString>?
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: pastor от Декабрь 06, 2009, 23:54
Как можна оптимизировать?
Добавлять данные в хэш по мере заполнения таблицы. Худший вариант - заполнена вся таблица
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 06, 2009, 23:56
QHash<QPair<int,int>, QVector<QString>>
Да, типа того. BTW: А зачем QVector<QString>? 2 роли - 2 элемента вектора (всего я буду использовать только 2 основные роли дисплей и редактиров..) или вместо вектора QPair<QString,QString>??????
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: pastor от Декабрь 07, 2009, 00:01
2 роли - 2 элемента вектора (всего я буду использовать только 2 основные роли дисплей и редактиров..) или вместо вектора QPair<QString,QString>??????
А у тебя редактируемые и отображаемые данные будут отличаться? C++ (Qt) QHash<QPair<int,int>, QString>
Взгляни хотябы на это: examples/itemviews/editabletreemodel
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 07, 2009, 00:04
2 роли - 2 элемента вектора (всего я буду использовать только 2 основные роли дисплей и редактиров..) или вместо вектора QPair<QString,QString>??????
А у тебя редактируемые и отображаемые данные будут отличаться? C++ (Qt) QHash<QPair<int,int>, QString>
Да будут - в каждой ячейке поработает парсер: ввел 2+2 - получил 4 (видешь в ячейке 4, редактируешь ячейку 2+2)
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: lit-uriy от Декабрь 07, 2009, 04:26
а я бы всё в одну роль воткнул, только формулу. А считать можно делегата заставить, тогда считать будет только то, что пользователю показывать надо.
Плюс при раскладе с интами, невозможно будет развивать этот "эксель", например приспичит добавить функцию: "Сцепить (A1, B1)" А в каждой из ячеек текст, тогда в результате должен быть тоже текст, но в int его уже не воткнёшь.
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 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
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: lit-uriy от Декабрь 08, 2009, 05:33
тебе за каким лешим, дерево, ты с таблицей сначала разберись.
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 09, 2009, 23:56
тебе за каким лешим, дерево, ты с таблицей сначала разберись.
Так на примере дерева хочу разобратся с таблицей (интересный создан итем для дерева). Хочу понять как итем работает с деревом. Итем-ячейка в примере или child для parent? child- своя таблица с колонками строками
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 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 уже есть)
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 13, 2009, 17:14
Как решить проблему с большим потребленией памяти для QAbstractTableModel (таблица 5000*5000- забита строками QString)
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: Igors от Декабрь 13, 2009, 18:09
Как решить проблему с большим потребленией памяти для QAbstractTableModel (таблица 5000*5000- забита строками QString)
Всегда есть ЗАДАЧА и она определяет что нужно а что нет. Если Вы делаете "просто таблицу" - это, скажем, тема лабораторной работы и сделать это можно за несколько дней или быстрее. А если Вы делаете "таблицу которая работает с большими данными" (1-2 Gb и более) - то это уже совсем др. задача которая может быть темой курсового или даже дипломного проекта - потому что работы в десятки раз больше. Поэтому не начинайте обсуждать серьезные вещи "просто так", из баловства. Сделайте сначала "просто таблицу" - до работы с большими данными Вам еще пахать и пахать :)
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 13, 2009, 18:16
Как решить проблему с большим потребленией памяти для QAbstractTableModel (таблица 5000*5000- забита строками QString)
Всегда есть ЗАДАЧА и она определяет что нужно а что нет. Если Вы делаете "просто таблицу" - это, скажем, тема лабораторной работы и сделать это можно за несколько дней или быстрее. А если Вы делаете "таблицу которая работает с большими данными" (1-2 Gb и более) - то это уже совсем др. задача которая может быть темой курсового или даже дипломного проекта - потому что работы в десятки раз больше. Поэтому не начинайте обсуждать серьезные вещи "просто так", из баловства. Сделайте сначала "просто таблицу" - до работы с большими данными Вам еще пахать и пахать :) В том то и дело что уже есть таблица на базе QTableWidget (сортировка, поиск/замена, вставка, копирования, вырезание, пересчёт ячеек, ячейка вычесляется с помощью парсера и т.д.)
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 13, 2009, 18:23
Примитивная таблица из QTableWidget готова, теперь можете ответить на вопрос про модель? Я просто уже курсач делаю месяц и хочу сделать его продуманным.
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: Igors от Декабрь 13, 2009, 18:49
Примитивная таблица из QTableWidget готова, теперь можете ответить на вопрос про модель? Я просто уже курсач делаю месяц и хочу сделать его продуманным.
Работа с большими данными предполагает свап на диск, организацию подкачки страницами и.т.п. Это непросто даже для данных фиксированной длины. Для данных как QString (т.е. произвольного размера) трудности многократно возрастают. Короче это совсем не "маленькое дополнение/фича" к уже имеющейся таблице, а новая работа которая превышает выполненную во много раз. Как правило, если данные велики, намного проще и лучше использовать БД чем управлять такими данными самому. Но не везде это подходит (напр для тех же excel таблиц БД может быть недостаточно гибкой). Я бы посоветовал думать реально и в рамках реальной задачи а не "растекаться мыслью по древу". Обсуждать таблицу 5Кх5К имеет смысл только если она реально есть (т.е. есть заказчик которому такая вещь нужна и который готов платить за нее). Иначе все мгновенно превращается в беспредметные фантазии (что я и вижу в запущенных Вами темах :))
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: lit-uriy от Декабрь 13, 2009, 20:09
Igors, ты ему дай ссылку на свой текстовый редактор для огромных файлов, пусть по изучает.
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 13, 2009, 20:31
Igors, ты ему дай ссылку на свой текстовый редактор для огромных файлов, пусть по изучает.
Можно пример текстового редактора??
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: Igors от Декабрь 13, 2009, 20:47
Igors, ты ему дай ссылку на свой текстовый редактор для огромных файлов, пусть по изучает.
Можна пример текстового редактора?? МожнО http://www.prog.org.ru/topic_11267_0.html Ну то правда не редактор а вьюер и не на всех платформах он работает. Исходники смотреть можно но необязательно, просто почитайте тему и поймите что это совсем НЕ просто и незачем лезть в проблемы больших данных "просто так".
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 13, 2009, 21:05
Igors, ты ему дай ссылку на свой текстовый редактор для огромных файлов, пусть по изучает.
Можна пример текстового редактора?? МожнО http://www.prog.org.ru/topic_11267_0.html Ну то правда не редактор а вьюер и не на всех платформах он работает. Исходники смотреть можно но необязательно, просто почитайте тему и поймите что это совсем НЕ просто и незачем лезть в проблемы больших данных "просто так". big text ->LargeTextView не компилится (проблема с линкованием) 1>------ Build started: Project: LargeTextView, Configuration: Debug Win32 ------ 1>MOC LargeTextView.h 1>Compiling... 1>moc_MainWindow.cpp 1>moc_LargeTextView.cpp 1>main.cpp 1>MainWindow.cpp 1>LargeTextView.cpp 1>Generating Code... 1>Linking... 1>MainWindow.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall QFormBuilder::~QFormBuilder(void)" (__imp_??1QFormBuilder@@UAE@XZ) referenced in function "class QWidget * __cdecl `anonymous namespace'::LoadWidget(class QWidget *,char const *)" (?LoadWidget@?A0x125fbeec@@YAPAVQWidget@@PAV2@PBD@Z) 1>MainWindow.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual class QWidget * __thiscall QAbstractFormBuilder::load(class QIODevice *,class QWidget *)" (__imp_?load@QAbstractFormBuilder@@UAEPAVQWidget@@PAVQIODevice@@PAV2@@Z) referenced in function "class QWidget * __cdecl `anonymous namespace'::LoadWidget(class QWidget *,char const *)" (?LoadWidget@?A0x125fbeec@@YAPAVQWidget@@PAV2@PBD@Z) 1>MainWindow.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall QFormBuilder::QFormBuilder(void)" (__imp_??0QFormBuilder@@QAE@XZ) referenced in function "class QWidget * __cdecl `anonymous namespace'::LoadWidget(class QWidget *,char const *)" (?LoadWidget@?A0x125fbeec@@YAPAVQWidget@@PAV2@PBD@Z) 1>debug\LargeTextView.exe : fatal error LNK1120: 3 unresolved externals 1>Build log was saved at "file://f:\Downloads\Compressed\bi_text\BigText\Sources\LargeTextView\debug\BuildLog.htm" 1>LargeTextView - 4 error(s), 0 warning(s) ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: Igors от Декабрь 13, 2009, 21:08
big text ->LargeTextView не компилится (проблема с линкованием)
Нужна библиотека QtDesigner
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 13, 2009, 21:12
big text ->LargeTextView не компилится (проблема с линкованием)
Нужна библиотека QtDesigner У меня он есть, подключаю - говорит немогу найти. В чём дело?
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: lit-uriy от Декабрь 14, 2009, 07:56
в pro-файле отсутствует строчка: CONFIG += designer
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: lit-uriy от Декабрь 14, 2009, 08:18
Igors, в той теме закинул коррективы программы.
Название: Re: Для таблицы типа exel, spreadsheet. Помогите новичку.
Отправлено: daimon от Декабрь 14, 2009, 11:16
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 уже есть)
|