Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. QSqlTableModel - distinguish between existed and new table rows
Forum Updated to NodeBB v4.3 + New Features

QSqlTableModel - distinguish between existed and new table rows

Scheduled Pinned Locked Moved Solved Qt for Python
4 Posts 2 Posters 368 Views 2 Watching
  • 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.
  • S Offline
    S Offline
    StarterKit
    wrote on last edited by StarterKit
    #1

    Hi, all,
    I'm a bit puzzled how to work with deleted rows in QSqlTableModel so below is a code example with pictures of how it works and questions.

    The code: I have very simple sqlite database d1.sqlite that contains only 1 table t1 with 2 fields id and value. It is populated with 3 rows of data:

    id |  value
    ---|-------
     1 |  aaa
     2 |  bbb
     3 |  ccc
    

    My code displays this table in QTableView and has 2 buttons. "Add" button allows to insert one more row into the table and "Remove" buttons deletes currently selected row.
    Important thing - I have self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) because in real code I would like to have more control about when I submit or rollback changes.

    Here you may see how this code works:
    illustration

    1. Just after start and selection of 1st row. Table shows 3 rows from the database.
    2. Button "Remove" was pressed and 2nd row was selected. You may see that 1st row is marked with exclamation sign ! - this is how Qt indicates that row was deleted.
    3. Button "Add" was pressed. You may see that 4th row was added to the table and this row is marked with asterisk * - this is how Qt indicates that this is a new row.
    4. New, 4th row, was selected.
    5. Button "Remove" was pressed again. 4th row was correctly deleted and you may see that it disappeared from the table completely. It was not marked with ! as it happened with 1st row but was completely removed.

    Actually everything works right and logical, but... I've subclassed QSqlTableModel and overriden method removeRow(). My method keeps track of what was deleted from the table and I need to understand was row actually removed from the table by Qt or only marked for deletion (i.e. I need to know is the row still visible for the user or disappeared).
    The questions is - how to distinguish between these 2 cases?
    I remember that there was no way to check if row is marked for deletion in QSqlTableModel (I don't think that it have changed recently). So the question is actually - can I see somehow that row is a fresh one, not from the database? (without making explicit SQL query that isn't really good from resource consumption point of view...)

    Here is the code:

    from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QTableView, QPushButton, QAbstractItemView
    from PySide6.QtSql import QSqlDatabase, QSqlTableModel
    
    class DbWnd(QMainWindow):
        def __init__(self):
            super().__init__()
            self.centralwidget = QWidget()
            self.layout = QVBoxLayout()
            self.table = QTableView(self)
            self.table.setSelectionMode(QAbstractItemView.SingleSelection)
            self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
            self.layout.addWidget(self.table)
            self.add_button = QPushButton(self, text="Add")
            self.layout.addWidget(self.add_button)
            self.remove_button = QPushButton(self, text="Remove")
            self.layout.addWidget(self.remove_button)
            self.centralwidget.setLayout(self.layout)
            self.setCentralWidget(self.centralwidget)
    
            self.db = QSqlDatabase.addDatabase("QSQLITE", "D1")
            self.db.setDatabaseName("d1.sqlite")
            self.db.open()
            self.model = QSqlTableModel(parent=self, db=self.db)
            self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
            self.model.setTable("t1")
            self.table.setModel(self.model)
            self.model.select()
    
            self.add_button.clicked.connect(self.add_row)
            self.remove_button.clicked.connect(self.remove_row)
    
        def add_row(self):
            new_record = self.model.record()
            new_record.setValue("value", "xxx")
            self.model.insertRecord(-1, new_record)
    
        def remove_row(self):
            selection = self.table.selectionModel().selection().indexes()
            for idx in selection:
                self.model.removeRow(idx.row())
    
    def main():
        app = QApplication()
        wnd = DbWnd()
        wnd.show()
        return app.exec()
    
    S 1 Reply Last reply
    0
    • S StarterKit

      Hi, all,
      I'm a bit puzzled how to work with deleted rows in QSqlTableModel so below is a code example with pictures of how it works and questions.

      The code: I have very simple sqlite database d1.sqlite that contains only 1 table t1 with 2 fields id and value. It is populated with 3 rows of data:

      id |  value
      ---|-------
       1 |  aaa
       2 |  bbb
       3 |  ccc
      

      My code displays this table in QTableView and has 2 buttons. "Add" button allows to insert one more row into the table and "Remove" buttons deletes currently selected row.
      Important thing - I have self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) because in real code I would like to have more control about when I submit or rollback changes.

      Here you may see how this code works:
      illustration

      1. Just after start and selection of 1st row. Table shows 3 rows from the database.
      2. Button "Remove" was pressed and 2nd row was selected. You may see that 1st row is marked with exclamation sign ! - this is how Qt indicates that row was deleted.
      3. Button "Add" was pressed. You may see that 4th row was added to the table and this row is marked with asterisk * - this is how Qt indicates that this is a new row.
      4. New, 4th row, was selected.
      5. Button "Remove" was pressed again. 4th row was correctly deleted and you may see that it disappeared from the table completely. It was not marked with ! as it happened with 1st row but was completely removed.

      Actually everything works right and logical, but... I've subclassed QSqlTableModel and overriden method removeRow(). My method keeps track of what was deleted from the table and I need to understand was row actually removed from the table by Qt or only marked for deletion (i.e. I need to know is the row still visible for the user or disappeared).
      The questions is - how to distinguish between these 2 cases?
      I remember that there was no way to check if row is marked for deletion in QSqlTableModel (I don't think that it have changed recently). So the question is actually - can I see somehow that row is a fresh one, not from the database? (without making explicit SQL query that isn't really good from resource consumption point of view...)

      Here is the code:

      from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QTableView, QPushButton, QAbstractItemView
      from PySide6.QtSql import QSqlDatabase, QSqlTableModel
      
      class DbWnd(QMainWindow):
          def __init__(self):
              super().__init__()
              self.centralwidget = QWidget()
              self.layout = QVBoxLayout()
              self.table = QTableView(self)
              self.table.setSelectionMode(QAbstractItemView.SingleSelection)
              self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
              self.layout.addWidget(self.table)
              self.add_button = QPushButton(self, text="Add")
              self.layout.addWidget(self.add_button)
              self.remove_button = QPushButton(self, text="Remove")
              self.layout.addWidget(self.remove_button)
              self.centralwidget.setLayout(self.layout)
              self.setCentralWidget(self.centralwidget)
      
              self.db = QSqlDatabase.addDatabase("QSQLITE", "D1")
              self.db.setDatabaseName("d1.sqlite")
              self.db.open()
              self.model = QSqlTableModel(parent=self, db=self.db)
              self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
              self.model.setTable("t1")
              self.table.setModel(self.model)
              self.model.select()
      
              self.add_button.clicked.connect(self.add_row)
              self.remove_button.clicked.connect(self.remove_row)
      
          def add_row(self):
              new_record = self.model.record()
              new_record.setValue("value", "xxx")
              self.model.insertRecord(-1, new_record)
      
          def remove_row(self):
              selection = self.table.selectionModel().selection().indexes()
              for idx in selection:
                  self.model.removeRow(idx.row())
      
      def main():
          app = QApplication()
          wnd = DbWnd()
          wnd.show()
          return app.exec()
      
      S Offline
      S Offline
      StarterKit
      wrote on last edited by
      #2

      Ok, I was not able to find a generic solution.
      But I recognized that id is a key field in my tables and normally it shouldn't have 0 value. It means that for may particular case I can distinguish rows based on this field value - if it has non-zero value then row came from database otherwise it is a fresh row that was created but haven't been committed to the database yet.

      Do my question transforms - is there a way to ask for a new feature in Qt?
      There is https://bugreports.qt.io/ for Qt bugs but I'm not sure is it allowed to raise feature requests there.
      It is obvious that Qt tracks record status internally and it would be good to have it available as a read-only property of table-object. So it shouldn't require much efforts from developers but would be really useful and I would like to make such request but don't know how to do it in a right way.

      SGaistS 1 Reply Last reply
      0
      • S StarterKit

        Ok, I was not able to find a generic solution.
        But I recognized that id is a key field in my tables and normally it shouldn't have 0 value. It means that for may particular case I can distinguish rows based on this field value - if it has non-zero value then row came from database otherwise it is a fresh row that was created but haven't been committed to the database yet.

        Do my question transforms - is there a way to ask for a new feature in Qt?
        There is https://bugreports.qt.io/ for Qt bugs but I'm not sure is it allowed to raise feature requests there.
        It is obvious that Qt tracks record status internally and it would be good to have it available as a read-only property of table-object. So it shouldn't require much efforts from developers but would be really useful and I would like to make such request but don't know how to do it in a right way.

        SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        The ticketing system is used for both bugs and feature requests.

        As for how the internal state is managed, you can directly check the implementation of the model classes to see how it is done.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        S 1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          The ticketing system is used for both bugs and feature requests.

          As for how the internal state is managed, you can directly check the implementation of the model classes to see how it is done.

          S Offline
          S Offline
          StarterKit
          wrote on last edited by
          #4

          @SGaist , ok thanks.
          So I created QTBUG-115145 with this proposal, lets see.
          This topic is solved.

          1 Reply Last reply
          0
          • S StarterKit has marked this topic as solved on

          • Login

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