Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTableView navigation and QSqlTableModel.editStrategy OnFieldChange

QTableView navigation and QSqlTableModel.editStrategy OnFieldChange

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 1.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Aiolos
    wrote on last edited by
    #1

    Hi,

    I have a QTableView with a QSqlTableModel.
    The navigation is fine when editstrategy of model is set with OnManualSubmit but I lost focus when I press Tab key when editStaegy is OnFieldChange, which is my need.
    I tried many things but nothing works and the only topics I found with that issue had no answers.

    Can you help me ?

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      I'm not sure I got what your problem is.

      try adding connect(tableModel,&QSqlTableModel::dataChanged,[]()->void{qDebug("Data was submitted!");});

      if you see the debug output but the database is not updated, something weird is going on

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      1
      • A Offline
        A Offline
        Aiolos
        wrote on last edited by
        #3

        My database is updated, the only problem is the navigation in TableView.
        I'd like to start editing the first cell then press tab key and continue with the next cell but when I press tab with the OnFieldChange strategy I don't access to any cell, I loose the TableView focus, probably because it update the database

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4

          Ok, I see where the problem might come from. by "continue with the next cell" you mean the next column in the same row?

          If so the problem comes from QSqlTableModel::selectRow

          if (needsAddingToCache) {
                  d->cache[row].refresh(exists, newValues);
                  emit headerDataChanged(Qt::Vertical, row, row);
                  emit dataChanged(createIndex(row, 0), createIndex(row, columnCount() - 1));
              }
          

          basically it emits dataChanged for the entire row regardless of how many cells actually changed. to solve it you'll need to add the private side of Qt (QT += sql-private) and subclass QSqlTableModel and reimplement QSqlTableModel::selectRow like below:

          bool QSqlTableModel::selectRow(int row)
          {
              Q_D(QSqlTableModel);
          
              if (row < 0 || row >= rowCount())
                  return false;
          
              const int table_sort_col = d->sortColumn;
              d->sortColumn = -1;
              const QString table_filter = d->filter;
              d->filter = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement,
                                                        d->tableName,
                                                        primaryValues(row),
                                                        false);
              static const QString wh = Sql::where() + Sql::sp();
              if (d->filter.startsWith(wh, Qt::CaseInsensitive))
                  d->filter.remove(0, wh.length());
          
              QString stmt;
          
              if (!d->filter.isEmpty())
                  stmt = selectStatement();
          
              d->sortColumn = table_sort_col;
              d->filter = table_filter;
          
              if (stmt.isEmpty())
                  return false;
          
              bool exists;
              QSqlRecord newValues;
          
              {
                  QSqlQuery q(d->db);
                  q.setForwardOnly(true);
                  if (!q.exec(stmt))
                      return false;
          
                  exists = q.next();
                  newValues = q.record();
              }
          
              bool needsAddingToCache = !exists || d->cache.contains(row);
          	QVector<int> colsChanged;
              if (!needsAddingToCache) {
                  const QSqlRecord curValues = record(row);
                  needsAddingToCache = curValues.count() != newValues.count();
                  if (!needsAddingToCache) {
                      // Look for changed values. Primary key fields are customarily first
                      // and probably change less often than other fields, so start at the end.
                      for (int f = curValues.count() - 1; f >= 0; --f) {
                          if (curValues.value(f) != newValues.value(f)) {
                              colsChanged << f;
                          }
                      }
                  }
              }
          
              if (needsAddingToCache) {
                  d->cache[row].refresh(exists, newValues);
                  emit headerDataChanged(Qt::Vertical, row, row);
                  emit dataChanged(createIndex(row, 0), createIndex(row, columnCount() - 1));
              }
          	else if(!colsChanged.isEmpty()){
          		d->cache[row].refresh(exists, newValues);
          		emit headerDataChanged(Qt::Vertical, row, row);
          		for(int singleCol : colsChanged)
          			emit dataChanged(createIndex(row, singleCol), createIndex(row, singleCol));
          		
          	}
          
              return true;
          }
          

          Edit:
          I think this problem is related to https://bugreports.qt.io/browse/QTBUG-47078 too

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          1
          • A Offline
            A Offline
            Aiolos
            wrote on last edited by
            #5

            Yes, I wanted to mean : "next column in the same row".

            I forgot to say that I'm on Qt 4.8, so I haven't : QSqlTableModel::selectRow

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved