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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: добавление данных в CustomTableModel  (Прочитано 4374 раз)
korel
Гость
« : Май 18, 2010, 11:06 »

Суть того, что делаю: есть файл до млн. строк, нужно его считать и записать данные в таблицу, а потом по этим данным рисовать графики. По скольку мне нужны QCheckBoxы в хедерах использую QTableView.
При считывании данных с файла - отправляю QStringList в MainWindow см. код.

В общем возникла проблема: при создании своей модели таблицы я переопределил все, на сколько я разобрался в том, что нужно переопределить, методы. Добавляю с помощью setData() данные в модель, но они не добавляются insertColumns() возвращает false.
Я тут, было, подумывал пробежаться по файлу(определить количество строк и столбцов), а потом, в методах rowCount() и columnCount() возвращать эти значения.

Может быть есть смысловые ошибки - но я пока их определить не могу. Буду благодарен за дельные советы.

Код:
class CustomTableModel : public QAbstractTableModel
{
    Q_OBJECT

    QList<QStringList> fileDataList;

public:
    CustomTableModel(QObject *parent = NULL):QAbstractTableModel(parent)
    {}

    int rowCount(const QModelIndex &parent = QModelIndex()) const
    {
        return fileDataList.size();
    }

    int columnCount(const QModelIndex &parent = QModelIndex()) const
    {
        if(!fileDataList.isEmpty())
            return fileDataList.at(0).size();
        return -1;
    }

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
    {
        if(!index.isValid())
            return QVariant();
        if(index.row() >= fileDataList.size() || index.row() < 0)
            return QVariant();
        if(role == Qt::DisplayRole || role == Qt::EditRole)
            return fileDataList.at(index.row()).at(index.column());
        else
            return QVariant();
    }

    bool setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if(index.isValid() && role == Qt::EditRole)
        {
            fileDataList[index.row()].replace(index.column(), value.toString());
            emit dataChanged(index, index);
            return true;
        }
        return false;
    }

    bool insertRows(int row, int count, const QModelIndex &parent)
    {
        beginInsertRows(QModelIndex(), row, row + count);

        endInsertRows();
    }
};
class Reader : public QObject
{
    Q_OBJECT

public:
    Reader(QObject *parent = NULL);
    void readFile(const QString&);

signals:
    void fileData(QStringList&);
};

Reader::Reader(QObject *parent):QObject(parent)
{}

void Reader::readFile(const QString &path)
{
    QFile file(path);
    if(file.open(QIODevice::ReadOnly))
    {
        while(!file.atEnd())
        {
            QString str(file.readLine());
            QStringList strList(str.split(" ", QString::SkipEmptyParts));
            emit fileData(strList);
        }
        file.close();
    }
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

    QAction *pActionOpen;
    QAction *pActionDraw;
    QAction *pActionClear;
    QToolBar *pToolBar;
    QStatusBar *pStatusBar;
    QVBoxLayout *pVLayout;
    QHBoxLayout *pHLayout;
    QWidget *pMainWidget;
    QTableView *pTableView;

    Reader *pReader;
    CustomTableModel *pModel;
    CustomHeader *pCustomHeader;

    int rCount;

public:
    MainWindow(QWidget *parent = NULL);

public slots:
    void openFileDlg();
    void clearTable(){}
    void drawCurve(){}

    void setFileData(QStringList&);
};

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),
                                        pActionOpen(NULL),
                                        pActionDraw(NULL),
                                        pActionClear(NULL),
                                        pToolBar(new QToolBar("Linker")),
                                        pStatusBar(new QStatusBar),
                                        pVLayout(new QVBoxLayout),
                                        pHLayout(new QHBoxLayout),
                                        pMainWidget(new QWidget),
                                        pTableView(new QTableView),
                                        pReader(new Reader),
                                        pModel(new CustomTableModel),
                                        pCustomHeader(new CustomHeader),
                                        rCount(0)
{
    QRect screen = QApplication::desktop()->screenGeometry(QDesktopWidget().screenNumber(this));
    setGeometry(screen.width()/4, screen.height()/4, screen.width()/2, screen.height()/2);
    setWindowTitle("Telemetry");
    setWindowIcon(QIcon("../img/table_gear.png"));

    setStatusBar(pStatusBar);
    setCentralWidget(new QTableWidget);//only for start window view

    addToolBar(Qt::TopToolBarArea, pToolBar);

    pActionOpen = pToolBar->addAction(QIcon("../img/folder_explore.png"), "Open telemetry file...", this, SLOT(openFileDlg()));
    pActionOpen->setShortcut(QKeySequence(tr("Ctrl+o")));
    pActionClear = pToolBar->addAction(QIcon("../img/cross.png"), "Clear table", this, SLOT(clearTable()));
    pActionDraw = pToolBar->addAction(QIcon("../img/chart_curve.png"), "Draw data from checked columns...", this, SLOT(drawCurve()));
    pActionDraw->setShortcut(QKeySequence(tr("Ctrl+d")));

    connect(pReader, SIGNAL(fileData(QStringList&)), this, SLOT(setFileData(QStringList&)));
    //connect(pReader, SIGNAL(fileData(QStringList&)), pModel, SLOT(insertFileDataList(QStringList&)));
}

void MainWindow::openFileDlg()
{
    QString sourceFileName = QFileDialog::getOpenFileName(this, tr("Open file..."), QString(),
                                                        tr(";; All files(*.*)") );

    if(sourceFileName.contains("_TMF"))
    {
        qApp->processEvents();
        pReader->readFile(sourceFileName);
    }
    else if(sourceFileName.isEmpty())
        return;
    else
    {
        QMessageBox box(QMessageBox::Information, "File open message", "Wrong file format", QMessageBox::Ok);
        box.exec();
    }
}

void MainWindow::setFileData(QStringList &strList)
{
    QStringList list = strList;
    qDebug()<<"new QStringList:\n";
    qDebug()<<"row insert flag: " << pModel->insertRow(rCount, QModelIndex());
    qDebug()<<"columns insert flag: " <<pModel->insertColumns(0, list.size(), QModelIndex());
    for(int i=0;i<list.size();++i)
    {
        qDebug()<<"column insert flag: " << pModel->insertColumn(i, QModelIndex());
        pModel->setData(pModel->index(rCount, i, QModelIndex()), "123", Qt::EditRole);
        qDebug()<<"QVariant: " << pModel->data(pModel->index(rCount, i, QModelIndex()), Qt::DisplayRole).toString();
    }
    qDebug()<<"\n";
    ++rCount;
}


 
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #1 : Май 18, 2010, 14:03 »

вы бы значение бы возвращали из функций
если вам нужно отображать тот список, то insertRows вообще не нужен
а вот flags не помешали бы
зачем делать инсерт колонок (к-ый даже не реализован, неясно)

если вы хотите добавить строку в таблицу, то а) надо изменить данные (то есть fileDataList) б) уведомить об этом модель и вьюху (с помощью методов beginInsertRows/endInsertRows). Первого у вас вообще нет.
Если в пустую делать пункт б (ваш метод insertRows, то после вызова endInsertRows модель проверяет свое состояние - то что метод rowCount() вернет значение "было + сколько строк добавили", а у вас оно не изменилось ("было"), модель об этом в консоль должна ругаться)
Возможно будет достаточно в методе insertRows сделать вставку пустой строки в fileDataList. А по хорошему, надо делать отдельный метод добавления целой строки (и не использовать для этого setData)
« Последнее редактирование: Май 18, 2010, 14:18 от Авварон » Записан
crossly
Гость
« Ответ #2 : Май 18, 2010, 14:27 »

Цитировать
Добавляю с помощью setData() данные в модель, но они не добавляются insertColumns() возвращает false.
так он у вас не реализован...  метод базового класса ничего не делает.... только возвращает false
Записан
korel
Гость
« Ответ #3 : Май 18, 2010, 14:49 »

вы бы значение бы возвращали из функций
если вам нужно отображать тот список, то insertRows вообще не нужен
а вот flags не помешали бы
зачем делать инсерт колонок (к-ый даже не реализован, неясно)

если вы хотите добавить строку в таблицу, то а) надо изменить данные (то есть fileDataList) б) уведомить об этом модель и вьюху (с помощью методов beginInsertRows/endInsertRows). Первого у вас вообще нет.
Если в пустую делать пункт б (ваш метод insertRows, то после вызова endInsertRows модель проверяет свое состояние - то что метод rowCount() вернет значение "было + сколько строк добавили", а у вас оно не изменилось ("было"), модель об этом в консоль должна ругаться)
Возможно будет достаточно в методе insertRows сделать вставку пустой строки в fileDataList. А по хорошему, надо делать отдельный метод добавления целой строки (и не использовать для этого setData)

т.е насколько я понял мне дня того, чтобы добавить данные в модель нужно создать метод например insertToModel(QStringList&). В нем добавляю данные в fileDataList, после чего вызываю beginInsertRows() и endInsertRows().
Записан
crossly
Гость
« Ответ #4 : Май 18, 2010, 14:53 »

для этого есть стандартный метод insetRows.... вам нужно переопределить именно его... все прекрасно описано в документации по MVC...
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #5 : Май 18, 2010, 15:02 »

не после а до и после (для того они бегин и энд)
Записан
korel
Гость
« Ответ #6 : Май 18, 2010, 15:13 »

не после а до и после (для того они бегин и энд)

Сейчас попробую все это дело написать. Отпишусь сразу как что то получится(или не получится))) )
Записан
korel
Гость
« Ответ #7 : Май 18, 2010, 15:20 »

для этого есть стандартный метод insetRows.... вам нужно переопределить именно его... все прекрасно описано в документации по MVC...
Спасибо за советы. Сейчас все попробую на практике испытать.
Записан
korel
Гость
« Ответ #8 : Май 18, 2010, 16:50 »

Спасибо, все получилось)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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