Custom table model is not working...



  • Hello,
    I developed a custom table model for displaying the contents of a text file....But nothing is displaying in the view...
    Please tell me whats changes i need to do for this program....

    mainwindow.h
    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    #include <QtCore>
    #include <QtGui>

    #include <QMainWindow>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();
    

    private:
    Ui::MainWindow *ui;
    };

    class MulModel : public QAbstractTableModel
    {
    public:
    MulModel( QString filename, QObject *parent = 0 );
    Qt::ItemFlags flags( const QModelIndex &index ) const;
    QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
    QVariant headerData( int section, Qt::Orientation orientation,
    int role = Qt::DisplayRole ) const;
    int rowCount( const QModelIndex &parent = QModelIndex() ) const;
    int columnCount( const QModelIndex &parent = QModelIndex() ) const;

    void ReadFromFile(QString filename);
    void PutToModel(QStringList lines);

    QString cell_value(int row, int col);
    void skipToRow(int row);

    private:
    QString file;
    QStringList LineList;
    int m_rows;
    int m_columns;
    };
    #endif // MAINWINDOW_H
    @

    mainwindow.cpp
    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QtCore>
    #include <QtGui>
    #include <iostream>
    using namespace std;
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    MulModel::MulModel( QString filename, QObject *parent ) :
    QAbstractTableModel( parent )
    {
    file=filename;
    ReadFromFile(file);
    }

    void MulModel::ReadFromFile(QString file)
    {
    QStringList AllLinesOfFile;
    QString line;
    QFile filename(file);
    if( !filename.exists() )
    {
    cout<<"FILE DOES NOT EXIST---------------------------!"<<endl;
    }
    if( !filename.open(QIODevice::ReadOnly ) ) // It exists, open it
    {
    cout<<"FILE COULD NOT OPENED---------!!!!"<<endl;
    }
    int loop_control=0;
    while((loop_control==0) && !filename.atEnd())
    {
    line=filename.readLine();
    if(line.contains("------------"))
    {
    loop_control=1;
    }
    }
    while(!filename.atEnd()) //while((c==1 && !f.atEnd()))
    {
    line=filename.readLine();
    AllLinesOfFile.append(line);
    }
    filename.close();
    PutToModel(AllLinesOfFile);
    }

    void MulModel::PutToModel(QStringList lines)
    {

    int row=0;
    int colCount;
    foreach(QString line,lines)
    {
    if(!line.contains("END"))
    {

    QStandardItemModel *model = new QStandardItemModel;
    LineList=line.split(" ",QString::SkipEmptyParts);
    colCount=LineList.count();

    for ( int col = 0; col < colCount; ++col )
    {
    QList<QStandardItem *> Lrow;

            QStandardItem *item = new QStandardItem;
            item->setData(LineList.at(col), Qt::DisplayRole);
    
            Lrow.append(item);
    

    model->appendRow(Lrow);
    }

    row ++;
    }
    m_columns=colCount;
    m_rows=row;
    }

    cout<<" row count:"<<m_rows<<" col:"<<m_columns<<endl;

    }

    int MulModel::rowCount( const QModelIndex &parent ) const
    {
    cout <<"Called RowCount: "<<m_rows<<endl;
    return m_rows;
    }

    int MulModel::columnCount( const QModelIndex &parent ) const
    {
    cout <<"Called Column Count: "<<m_columns<<endl;
    return m_columns;
    }

    QVariant MulModel::data( const QModelIndex &index, int role ) const
    {
    cout<<" data------------row:"<<index.row()<<endl;
    if (!index.isValid())
    return QVariant::Invalid;

        if (index.row() >= LineList.size())
            return QVariant::Invalid;
    
        if (role == Qt::DisplayRole)
            return LineList.at(index.row());
        else
            return QVariant::Invalid;
    

    }

    QVariant MulModel::headerData( int section,
    Qt::Orientation orientation, int role ) const
    {
    cout << "Called HeaderData, role = " << role <<endl;
    if( role != Qt::DisplayRole )
    return QVariant::Invalid;

    cout<<" HEDDD:"<<section+1<<endl;
    return QString::number(section+1);
    }

    Qt::ItemFlags MulModel::flags( const QModelIndex &index ) const
    {
    if(!index.isValid())
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    return Qt::NoItemFlags;
    }

    void MainWindow::on_pushButton_clicked()
    {

    QString fileName = QFileDialog::getOpenFileName(this,
    tr("Open tracker file"), "C:/Users/dnaik1/Desktop/fd", tr("tracker Files (*.txt)"));
    ui->lineEdit->setText(fileName);

    }

    void MainWindow::on_pushButton_2_clicked()
    {
    //MulModel model( 12, 12 );
    //QTableView table;
    //table.setModel( &model );
    //table.show();
    MulModel model(ui->lineEdit->text());
    ui->tableView->setModel( &model);

    }

    @

    main.cpp
    @
    #include <QtGui/QApplication>
    #include "mainwindow.h"
    #include <QtCore>
    #include <QtGui>
    int main( int argc, char **argv )
    {
    QApplication app( argc, argv );

    MainWindow w;
    w.show();

    return app.exec();
    }
    @



  • Hello. I think you have the problem become:

    MulModel model(ui->lineEdit->text());
    

    It is the local variable. When programm leave void MainWindow::on_pushButton_2_clicked() - pointer to model is bad.


    Sorry my English.



  • Apart from what kunashir said (which is indeed the primary reason why it's not working):
    Why are you creating an extra QStandardItemModel inside your abstract table model? In fact, you're not ever using it again, you're just leaking memory (model never gets deleted before the pointer leaves scope).
    Further, program cleaner. Your code right now is a mess with respect to indenting/case consistency. this is not eye candy but vital to creating working programs - and it increases the chances of people helping you.

    Another thing I've noticed: After PutToModel your LineList contains the last line of the text file, splitted by whitespace. But in your data() reimplementation you provide the contents of this LineList as rows and access them with index.row(). Apart from probably not doing what you intended, this will crash your program if the last line contains less words than the file contains lines.



  • ok...thank sfor your guidance....
    My requirement is simple....i just want to display the very large(around 1 gb) text file in table format...
    I tried using table widget it was unable to load even 100mb file...
    what should i do?
    is using model view helpful to tackle the problem?
    How should i start?
    will i get some refence at least for that?



  • Unfortunately your requirement isn't as simple as you think :)
    A 1 GiB text file that needs to be splitted by lines and columns will require alot of I/O work independent on the model approach.
    My suggestion is this: Open the file with a QTextStream and load chunks of, say 2000 lines to a buffer of lines that keeps track of the line number and the line content (e.g. QMap<int, QString>). Do this until you have read to the position the user is currently viewing, not further. If your buffer (the QMap) exceeds 2000 entries, clear it and save the byte offset of each line in some other storage (maybe QMap<int, int64> (meaning <"line number", "byte offset of line">)) so we'll be faster when viewing those positions at some point in the future. When you've reached the currently viewed lines, start splitting the visible lines by column and finally provide them with the model.
    If the user now scrolls down i.e. further than we've ever indexed lines, we just repeat the process, starting from the last indexed line (the lowest line of the previous view section). If the user scrolls up we load the lines from the QMap<int, QString> until we reach a line that's not in that buffer anymore. At this point we utilize the index map QMap<int, int64> by looking up the byte offset of the desired top line, position our text stream at that byte offset and start filling the QMap buffer again from that line on.

    If you're new to Model/View, I'd suggest not using it, because learning model/view from scratch, especially with such an intricate, buffering model, will be very hard and frustrating.
    Try to do it with a QTableWidget for example. The scrolling will be handled outside of the widget, so the widget will only contain so many rows as currently fit the height of the widget. If the user scrolls (with a scrollbar widget or buttons), the cells of the table widget are updated accordingly, not actually scrolled themselves.

    If you've got that running, you can start building a model and a view for this.



  • Thanks a lot for your detailed explanation...ya i'll try using table widget itself...
    and will come back to u if i face any more issue...:)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.