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. QTableView rows disabled?

QTableView rows disabled?

Scheduled Pinned Locked Moved Solved Qt for Python
9 Posts 3 Posters 461 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.
  • M Offline
    M Offline
    MasterQ
    wrote on 24 Nov 2024, 15:39 last edited by
    #1

    Hi,

    i've implemented my first QTableView with PySide6. It is quite a 1:1 copy of a C++ solution.

    But contrary to C++ the table is like all rows are "disabled". They are grayed out.

    Python:
    cc216a4f-7d5b-4237-95ce-83ddad185337-grafik.png

    C++:
    65545178-fc9e-4b59-9b84-cd94531b34e6-grafik.png

    How can that happen? Or better, what I am doing wrong?

    My code to initialize the widget:

    Python:

    class AccountView(QWidget): 
      def __init__(self, parent=None):
            super().__init__(parent)
            self.ui = Ui_AccountView()
            self.ui.setupUi(self)
    
            self.ui.tableView.setObjectName(self.AccountViewTabIndentifier)
            self.ui.tableView.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
            self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
            self.ui.tableView.setAlternatingRowColors(True)
            self.ui.tableView.horizontalHeader().setStretchLastSection(True)
    
            self.dbcontext = AccountDbContext()
            self.ui.tableView.setModel(self.dbcontext.frontendmodel)
            self.dbcontext.backendmodel.select()
    
            self.ui.tableView.setColumnHidden(0, True)
    
            self.ui.tableView.setEditTriggers(QAbstractItemView.EditTrigger.SelectedClicked)
    
    

    C++:

       AccountView::AccountView(QWidget *parent) : QWidget(parent)
                                                    , ui(new Ui::AccountView) {
            ui->setupUi(this);
    
            ui->tableView->setObjectName(AccountViewTabIndentifier);
            ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
            ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
            ui->tableView->setAlternatingRowColors(true);
            ui->tableView->horizontalHeader()->setStretchLastSection(true);
    
    
            m_dbcontext = new AccountDbContext();
            ui->tableView->setModel(m_dbcontext->FrontendModel());
            m_dbcontext->BackendModel()->select();
    
            ui->tableView->setColumnHidden(0, true);
    
            ui->tableView->setEditTriggers(QAbstractItemView::SelectedClicked);
        }
    

    Are there any settings I have overseen? I cannot find any real different between Python and C++ code.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 24 Nov 2024, 19:26 last edited by SGaist
      #3

      Hi,

      Did you check the actual values that are calculated for flags ?
      I do not have a Python interpreter at hand but I recall that some operations are not 100% translatable as is from C++.

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

      M 1 Reply Last reply 25 Nov 2024, 11:03
      0
      • M Offline
        M Offline
        MasterQ
        wrote on 24 Nov 2024, 15:59 last edited by
        #2

        here are also flags and data methods of the relevant data model

            def flags(self, index) -> Qt.ItemFlag:
                flags = super().flags(index)
                if index.isValid():
                    if not index.column() in self.editables:
                        flags &= ~Qt.ItemFlag.ItemIsEditable
                    if index.column() in self.bools:
                        flags |= Qt.ItemFlag.ItemIsUserCheckable
                return flags
        
            def data(self, proxyIndex, role=...) -> any:
                ret = super().data(proxyIndex, role)
                if proxyIndex.column() in self.bools:
                    match role:
                        case Qt.ItemDataRole.DisplayRole:
                            return None
                        case Qt.ItemDataRole.CheckStateRole:
                            return bool(super().data(proxyIndex, Qt.ItemDataRole.DisplayRole))
                        case Qt.ItemDataRole.EditRole:
                            return None
        
                if role == Qt.ItemDataRole.DisplayRole:
                    match proxyIndex.column():
                        case self.Datafield.BUCHUNGSTAG:
                            return datetime.fromisoformat(ret).strftime("%d.%m.%Y")
                        case self.Datafield.BETRAG:
                            return locale.format_string("%.2f", ret, grouping=True)
                        case self.Datafield.KATEGORIE:
                            categorie = [k for k in self.categories if k.id() == ret]
                            if len(categorie):
                                return categorie[0].nameShort()
                            return None
                        case _:
                            return ret
        
                if role == Qt.ItemDataRole.TextAlignmentRole:
                    if proxyIndex.column() == self.Datafield.BETRAG:
                        return Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter
                    return ret
        
                return ret
        
        
        J 1 Reply Last reply 25 Nov 2024, 09:32
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 24 Nov 2024, 19:26 last edited by SGaist
          #3

          Hi,

          Did you check the actual values that are calculated for flags ?
          I do not have a Python interpreter at hand but I recall that some operations are not 100% translatable as is from C++.

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

          M 1 Reply Last reply 25 Nov 2024, 11:03
          0
          • M MasterQ
            24 Nov 2024, 15:59

            here are also flags and data methods of the relevant data model

                def flags(self, index) -> Qt.ItemFlag:
                    flags = super().flags(index)
                    if index.isValid():
                        if not index.column() in self.editables:
                            flags &= ~Qt.ItemFlag.ItemIsEditable
                        if index.column() in self.bools:
                            flags |= Qt.ItemFlag.ItemIsUserCheckable
                    return flags
            
                def data(self, proxyIndex, role=...) -> any:
                    ret = super().data(proxyIndex, role)
                    if proxyIndex.column() in self.bools:
                        match role:
                            case Qt.ItemDataRole.DisplayRole:
                                return None
                            case Qt.ItemDataRole.CheckStateRole:
                                return bool(super().data(proxyIndex, Qt.ItemDataRole.DisplayRole))
                            case Qt.ItemDataRole.EditRole:
                                return None
            
                    if role == Qt.ItemDataRole.DisplayRole:
                        match proxyIndex.column():
                            case self.Datafield.BUCHUNGSTAG:
                                return datetime.fromisoformat(ret).strftime("%d.%m.%Y")
                            case self.Datafield.BETRAG:
                                return locale.format_string("%.2f", ret, grouping=True)
                            case self.Datafield.KATEGORIE:
                                categorie = [k for k in self.categories if k.id() == ret]
                                if len(categorie):
                                    return categorie[0].nameShort()
                                return None
                            case _:
                                return ret
            
                    if role == Qt.ItemDataRole.TextAlignmentRole:
                        if proxyIndex.column() == self.Datafield.BETRAG:
                            return Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter
                        return ret
            
                    return ret
            
            
            J Offline
            J Offline
            JonB
            wrote on 25 Nov 2024, 09:32 last edited by JonB
            #4

            @MasterQ
            As @SGaist says all that matters here is flags(), and probably Qt.ItemFlag.ItemIsEnabled (if the items are disabled rather than just non-editable) or Qt.ItemFlag.ItemIsEditable. Have you tried making your override just go return super().flags(index) with nothing else or comment out your override completely? Then you would know where the issue lies.

            1 Reply Last reply
            0
            • S SGaist
              24 Nov 2024, 19:26

              Hi,

              Did you check the actual values that are calculated for flags ?
              I do not have a Python interpreter at hand but I recall that some operations are not 100% translatable as is from C++.

              M Offline
              M Offline
              MasterQ
              wrote on 25 Nov 2024, 11:03 last edited by MasterQ
              #5

              @SGaist said in QTableView rows disabled?:

              Did you check the actual values that are calculated for flags ?

              Yes, but I was absently, obviously. I didn't recognize that detail.

              The default flags returned from PySide is of value 130 which is ItemIsEditable|ItemHasNeverChildren, while default flags from C++ is of value 163 which is additionally ItemIsEnabled|ItemIsSelectable.

              Oh dear, what a detail.

              S 1 Reply Last reply 25 Nov 2024, 11:08
              0
              • M MasterQ
                25 Nov 2024, 11:03

                @SGaist said in QTableView rows disabled?:

                Did you check the actual values that are calculated for flags ?

                Yes, but I was absently, obviously. I didn't recognize that detail.

                The default flags returned from PySide is of value 130 which is ItemIsEditable|ItemHasNeverChildren, while default flags from C++ is of value 163 which is additionally ItemIsEnabled|ItemIsSelectable.

                Oh dear, what a detail.

                S Offline
                S Offline
                SGaist
                Lifetime Qt Champion
                wrote on 25 Nov 2024, 11:08 last edited by
                #6

                @MasterQ That difference of behaviour between Python and C++ looks like a bug. Can you create a minimal script that shows this ?

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

                M 1 Reply Last reply 25 Nov 2024, 11:52
                0
                • S SGaist
                  25 Nov 2024, 11:08

                  @MasterQ That difference of behaviour between Python and C++ looks like a bug. Can you create a minimal script that shows this ?

                  M Offline
                  M Offline
                  MasterQ
                  wrote on 25 Nov 2024, 11:52 last edited by
                  #7

                  @SGaist said in QTableView rows disabled?:

                  @MasterQ That difference of behaviour between Python and C++ looks like a bug. Can you create a minimal script that shows this ?

                  That seems to be difficult. I tried this, which is very close to my setup here.

                  from PySide6.QtCore import QIdentityProxyModel
                  from PySide6.QtSql import QSqlTableModel
                  from PySide6.QtWidgets import QApplication, QMainWindow, QTableView
                  
                  
                  class MainWindow(QMainWindow):
                      def __init__(self, parent=None):
                          super().__init__(parent)
                  
                  class BackendModel(QSqlTableModel):
                      def __init__(self, parent=None):
                          super().__init__(parent)
                          print(self.insertColumn(0))
                          print(self.insertRow(0))
                  
                  class FrontendModel(QIdentityProxyModel):
                      def __init__(self, parent=None):
                          super().__init__(parent)
                  
                      def flags(self, index):
                          defaults = super().flags(index)
                          print(defaults)
                          return defaults
                  
                  app = QApplication()
                  window = MainWindow()
                  
                  tableview = QTableView()
                  frontendmodel = FrontendModel()
                  backendmodel = BackendModel()
                  frontendmodel.setSourceModel(backendmodel)
                  tableview.setModel(frontendmodel)
                  window.setCentralWidget(tableview)
                  
                  window.show()
                  app.exec()
                  
                  

                  But with this code I get a value of 161 and not 130 for flags. I am confused.

                  In BackendModel the flags method is not oberloaded , so it is giving the unmodified value from BackendModel. In my code I checked flags before any modification!

                  I haven't an idea why in the example above I get 161 and in my original code 130.

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    JonB
                    wrote on 25 Nov 2024, 12:52 last edited by
                    #8

                    Then you will have to break down/build up till you find the difference in your code! Start by removing "front end identity model", just test directly on model (maybe non-SQL one as well as SQL one) and build back up from there.

                    M 1 Reply Last reply 25 Nov 2024, 15:05
                    0
                    • J JonB
                      25 Nov 2024, 12:52

                      Then you will have to break down/build up till you find the difference in your code! Start by removing "front end identity model", just test directly on model (maybe non-SQL one as well as SQL one) and build back up from there.

                      M Offline
                      M Offline
                      MasterQ
                      wrote on 25 Nov 2024, 15:05 last edited by
                      #9

                      @JonB said in QTableView rows disabled?:

                      Then you will have to break down/build up till you find the difference in your code! Start by removing "front end identity model", just test directly on model (maybe non-SQL one as well as SQL one) and build back up from there.

                      If I would like to find a reason for that behavior!

                      At the moment I am satisfied to know about. There is an easy workaround as to set all flags by hand independently to what the framework does. That's enough for now. ... at least for me.

                      I am sorry, but to dig deeper into the issue is actually out of my scope.

                      1 Reply Last reply
                      0
                      • M MasterQ has marked this topic as solved on 27 Nov 2024, 12:26

                      1/9

                      24 Nov 2024, 15:39

                      • Login

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