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?
Forum Updated to NodeBB v4.3 + New Features

QTableView rows disabled?

Scheduled Pinned Locked Moved Solved Qt for Python
9 Posts 3 Posters 476 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.
  • MasterQM Offline
    MasterQM Offline
    MasterQ
    wrote on 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
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on 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

      MasterQM 1 Reply Last reply
      0
      • MasterQM Offline
        MasterQM Offline
        MasterQ
        wrote on 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
        
        
        JonBJ 1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on 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

          MasterQM 1 Reply Last reply
          0
          • MasterQM MasterQ

            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
            
            
            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on 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
            • SGaistS SGaist

              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++.

              MasterQM Offline
              MasterQM Offline
              MasterQ
              wrote on 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.

              SGaistS 1 Reply Last reply
              0
              • MasterQM MasterQ

                @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.

                SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on 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

                MasterQM 1 Reply Last reply
                0
                • SGaistS SGaist

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

                  MasterQM Offline
                  MasterQM Offline
                  MasterQ
                  wrote on 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
                  • JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on 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.

                    MasterQM 1 Reply Last reply
                    0
                    • JonBJ JonB

                      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.

                      MasterQM Offline
                      MasterQM Offline
                      MasterQ
                      wrote on 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
                      • MasterQM MasterQ 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