Results 1 to 20 of 24

Thread: custom QAbstractTableModel class updating QTableView

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    May 2016
    Posts
    13

    Default custom QAbstractTableModel class updating QTableView

    Hi all,

    I already read a few threads on this forum dealing with similar issues but didn't provide "the" solution.

    I built my own QAbstractTableModel class which fills a QTableView with data from a .csv file. The file is used for logging purposes and stores its (new) data every 10 minutes. The data is shown inside a QTableView but needs to be updated manually (button or closing and reopening the QDialog). What I want to achieve is that the view is automatically updated whenever new data is written to the .csv file.

    The code snippets of my TableModel looks as follows:
    Qt Code:
    1. int QCsvTableModel::rowCount(const QModelIndex &parent) const
    2. {
    3. Q_UNUSED(parent);
    4. return csvMatrix.rowCount();
    5. }
    6.  
    7. int QCsvTableModel::columnCount(const QModelIndex &parent) const
    8. {
    9. Q_UNUSED(parent);
    10. return csvMatrix.columnCount();
    11. }
    12.  
    13. QVariant QCsvTableModel::data(const QModelIndex &index, int role) const
    14. {
    15. if (index.isValid())
    16. if (role == Qt::DisplayRole || role == Qt::EditRole)
    17. return csvMatrix.at(index.row(), index.column());
    18. return QVariant();
    19. }
    20.  
    21. bool QCsvTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
    22. {
    23. if (index.isValid() && role == Qt::EditRole) {
    24. csvMatrix.setValue(index.row(), index.column(), value.toString());
    25.  
    26. emit dataChanged(index,index); // No difference if dataChanged is emitted or not
    27.  
    28. return true;
    29. }
    30.  
    31. return false;
    32. }
    To copy to clipboard, switch view to plain text mode 

    MainWindow source:
    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6.  
    7. QString fileName = ":/value.csv";
    8.  
    9. if (!fileName.isEmpty()) {
    10. QCsvTableModel *model = new QCsvTableModel(this);
    11.  
    12. QString extension = QFileInfo(QFile(fileName)).completeSuffix();
    13.  
    14. if (extension.toLower() == "csv") // known file extension
    15. model->loadFromFile(fileName);
    16.  
    17. ui->tableView->setModel(model);
    18. } // if fileName ..
    19.  
    20. connect(ui->tableView->model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(onModelsDataChanged(const QModelIndex&, const QModelIndex&)));
    21. //connect(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(onModelsDataChanged(const QModelIndex&, const QModelIndex&))); // Didn't work either ..
    22. }
    23.  
    24. void MainWindow::onModelsDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
    25. {
    26. Q_UNUSED(topLeft);
    27. Q_UNUSED(bottomRight);
    28.  
    29. qDebug() << "The data has changed." << endl;
    30. }
    To copy to clipboard, switch view to plain text mode 

    But the dataChanged() signal isn't fired at all and "The data has changed." never shows up.

    What am I missing? Any help is appreciated!

    Michael

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: custom QAbstractTableModel class updating QTableView

    The code you posted does not contain any call to setData(), which is where you emit dataChanged().

    Do you edit the table through the view?

    Cheers,
    _

  3. #3
    Join Date
    May 2016
    Posts
    13

    Default Re: custom QAbstractTableModel class updating QTableView

    Hi anda_skoa,

    thank you for replying!!
    the model gets it's data from the loadFromFile() method which looks as follows:
    Qt Code:
    1. bool QCsvTableModel::loadFromFile(const QString &fileName, const QChar &delim)
    2. {
    3. beginResetModel();
    4.  
    5. csvMatrix.clear();
    6. QChar delimiter;
    7. QFile file(fileName);
    8.  
    9. if (delim == 0) {
    10. QString extension = QFileInfo(file).completeSuffix();
    11. if (extension.toLower() == "csv")
    12. delimiter = QChar(';');
    13. }
    14. else if (delim == QChar('"'))
    15. return false; //the ONLY invalid delimiter is double quote (")
    16. else
    17. delimiter = delim;
    18. if (!file.isOpen())
    19. if (!file.open(QFile::ReadOnly|QFile::Text))
    20. return false;
    21.  
    22. QString temp;
    23. QChar lastCharacter;
    24. QTextStream in(&file);
    25. QList<QString> row;
    26.  
    27. while (true) {
    28. QChar character;
    29. in >> character;
    30. if (in.atEnd()) {
    31. if (lastCharacter == delimiter) //cases where last character is equal to the delimiter
    32. temp = "";
    33. checkString(temp, row, csvMatrix, delimiter, QChar('\n'));
    34. break;
    35. } else if (character == delimiter || character == QChar('\n'))
    36. checkString(temp, row, csvMatrix, delimiter, character);
    37. else {
    38. temp.append(character);
    39. lastCharacter = character;
    40. }
    41. }
    42.  
    43. file.close();
    44. in.flush();
    45. in.reset();
    46.  
    47. return true;
    48.  
    49. endResetModel();
    50. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by MichaH; 5th August 2016 at 10:10.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: custom QAbstractTableModel class updating QTableView

    That looks mostly good, but you need to do the endResetModel() before you return

    Regarding your original question: since this method doesn't emit dataChanged() (doesn't need to since it resets the model), why would the slot connected to the signal be called?

    Cheers,
    _

  5. #5
    Join Date
    May 2016
    Posts
    13

    Default Re: custom QAbstractTableModel class updating QTableView

    My bad! Did that already.

    The code right now looks as follows:
    Qt Code:
    1. bool QCsvTableModel::loadFromFile(const QString &fileName, const QChar &delim)
    2. {
    3. QCsvTableModel::beginResetModel();
    4. csvMatrix.clear();
    5. QChar delimiter;
    6. QFile file(fileName);
    7.  
    8. if (delim == 0) {
    9. QString extension = QFileInfo(file).completeSuffix();
    10. if (extension.toLower() == "csv")
    11. delimiter = QChar(';');
    12. }
    13. else if (delim == QChar('"'))
    14. return false; // The only invalid delimiter is double quote (")
    15. else
    16. delimiter = delim;
    17. if (!file.isOpen())
    18. if (!file.open(QFile::ReadOnly|QFile::Text))
    19. return false;
    20.  
    21. QString temp;
    22. QChar lastCharacter;
    23. QTextStream in(&file);
    24. QList<QString> row;
    25.  
    26. while (true) {
    27. QChar character;
    28. in >> character;
    29. if (in.atEnd()) {
    30. if (lastCharacter == delimiter) // Cases where last character is equal to the delimiter
    31. temp = "";
    32. checkString(temp, row, csvMatrix, delimiter, QChar('\n'));
    33. break;
    34. } else if (character == delimiter || character == QChar('\n'))
    35. checkString(temp, row, csvMatrix, delimiter, character);
    36. else {
    37. temp.append(character);
    38. lastCharacter = character;
    39. }
    40. }
    41.  
    42. file.close();
    43. in.flush();
    44. in.reset();
    45.  
    46. QCsvTableModel::endResetModel();
    47.  
    48. return true;
    49. }
    To copy to clipboard, switch view to plain text mode 

    I just need to update the data structure with replacing the csvMatrix variable since it gets all the model data. But apparently I'm completely lost on that one right now........

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: custom QAbstractTableModel class updating QTableView

    I am not sure I understand the current state correctly.

    Still something you need help with?

    Cheers,
    _

  7. #7
    Join Date
    May 2016
    Posts
    13

    Default Re: custom QAbstractTableModel class updating QTableView

    Well yes. The auto-update still doesn't work since I'm not able to figure out what else I'm missing..

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: custom QAbstractTableModel class updating QTableView

    But the initial loading works?

    Are you calling the same load method for updating or do you use something else?

    Cheers,
    _

  9. #9
    Join Date
    May 2016
    Posts
    13

    Default Re: custom QAbstractTableModel class updating QTableView

    The data shows up in my QTableView correctly but still when the data of the csv file changes (doesn't matter if that happens outside of the qt app or with a button which adds new data) it doesn't update/refresh itself. It only refreshes if the app is restarted or if the QDialog is closed and reopened.

  10. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: custom QAbstractTableModel class updating QTableView

    How do you handle these two cases?

    Do you watch the file for changes and then call the load method?

    What do you do in the slot connected to the button? Also reload the file?

    Cheers,
    _

  11. #11
    Join Date
    May 2016
    Posts
    13

    Default Re: custom QAbstractTableModel class updating QTableView

    When opening the dialog I've connected the dataChanged() signal to a slot which shows a debug message in the console. the connect() call returns true in debug.
    Qt Code:
    1. {
    2. ...
    3. connect(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(onModelsDataChanged(const QModelIndex&, const QModelIndex&)));
    4. ...
    5. }
    6.  
    7. void Dialog::onModelsDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
    8. {
    9. Q_UNUSED(topLeft);
    10. Q_UNUSED(bottomRight);
    11.  
    12. qDebug() << "YES" << endl;
    13.  
    14. // model->loadFromFile(fileName); // fileName = path/to/value.csv
    15. // ui->tableView->setModel(model);
    16. }
    To copy to clipboard, switch view to plain text mode 
    The commented lines (reloading the model) didn't make any difference.

    The button just increments a number when it's clicked and writes it to the file:
    Qt Code:
    1. void Dialog::onButtonPush()
    2. {
    3. QFile log(":/value.csv");
    4.  
    5. QTextStream stream(&log);
    6. x++;
    7.  
    8. if (log.open(QFile::WriteOnly | QFile::Truncate)) {
    9. stream << "Clicked button number;" << x << endl;
    10. ui->pushButton->setText(QString::number(x));
    11. }
    12.  
    13. log.flush();
    14. log.close();
    15. }
    To copy to clipboard, switch view to plain text mode 

    Button and tableview are on the same dialog window and the tableview is supposed to be updated as soon as the data changes - e.g. every time the button is clicked. The updating doesn't work though. :/

Similar Threads

  1. QAbstractTableModel, QTableView and restoreState.
    By cydside in forum Qt Programming
    Replies: 0
    Last Post: 10th August 2014, 11:41
  2. Replies: 0
    Last Post: 5th April 2011, 16:51
  3. Custom role in custom QAbstractTableModel
    By hailflex in forum Newbie
    Replies: 3
    Last Post: 10th December 2009, 12:09
  4. Performance with QTableView and QAbstractTableModel
    By MBex in forum Qt Programming
    Replies: 3
    Last Post: 25th February 2009, 08:04
  5. Replies: 3
    Last Post: 29th January 2009, 08:38

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.