【问题标题】:make QTableView column read-only using Python使用 Python 将 QTableView 列设为只读
【发布时间】:2016-10-27 11:17:36
【问题描述】:

我搜索了档案,发现了以下代码:

class ManifestModel: public QSqlTableModel
{
public: 
    ManifestModel(QObject * parent = 0, QSqlDatabase db = QSqlDatabase() ):
        QSqlTableModel(parent, db)
    { }
    ~ManifestModel() { }
    Qt::ItemFlags flags ( const QModelIndex & index ) const 
    {
        if (index.column() == 2)
            return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
        else
            return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
};

然后使用 ManifestModel 代替 QSqlTableModel。

这正是我需要做的,但我不懂 C++ 语法。有人可以帮我把它转换成 Python。我真的很感激。

【问题讨论】:

    标签: python pyqt qtableview


    【解决方案1】:

    这应该可以,但我没有测试它:

    from PyQt4.QtCore import Qt
    from PyQt4.QtSql import QSqlTableModel, QSqlDatabase
    
    
    class ManifestModel(QSqlTableModel):
    
        def __init__(self, parent=None, db=QSqlDatabase()):
            super(ManifestModel, self).__init__(parent, db)
    
        def flags(self, index):
            if (index.column() == 2):
                return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
            else:
                return Qt.ItemIsEnabled | Qt.ItemIsSelectable
    

    __init__ 方法等效于 C++ 构造函数ManifestModel()super 调用父构造函数,这里是QSqlTableModel。子类化时应始终遵循此模式。

    方法~ManifestModel()是析构函数,在python中一般不用担心,不需要定义方法。

    flags是一个类方法,C++语法

    TypeOfOutput functionName( typeOfParameter1 parameter1){}
    

    在 python 中有一个更简单的等价物:

    functionName(self, parameter1): 
    

    最后,C++ Qt:: 变为 Qt.QtCore.Qt.,具体取决于导入。

    【讨论】:

    • 我的建议是尝试使用 C++ 语法,C++ 中的 Qt 文档比 PyQt 文档好得多(我认为它更易于阅读和浏览)。
    • 看起来应该可以了。我下周上班时会测试它。看来我不应该感谢你?我同意 c++ 语法,但如果不学习编程 c++,我不知道如何做到这一点,我不想这样做。
    • 我正在尝试使用您提供给我的代码,但出现错误。
    • builtins.TypeError: flags() 接受 1 个位置参数,但给出了 2 个
    • 我通过添加“def flags(self, index):”修复了 flags() 错误,但现在我得到“builtins.NameError: name 'Qt' is not defined” 文档指出“这个枚举描述了一个项目的属性:'并且我看不到“项目”在哪里或为什么索引具有列属性。如果你愿意,我可以把我的代码发给你,但我不能在评论中这样做。
    【解决方案2】:

    这在 PyQt5 中有效:

    类ManifestModel(QtSql.QSqlTableModel):

    def __init__(self, parent=None, db=QtSql.QSqlDatabase()):
        super(ManifestModel, self).__init__(parent, db)
    
    def flags(self, index):
        if (index.column() == 4):
            return QtCore.Qt.ItemIsEnabled
        elif (index.column() == 6):
            return QtCore.Qt.ItemIsEnabled  
        else:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
    

    【讨论】:

      【解决方案3】:

      我知道这是一个旧帖子,但由于我有点挣扎,这是QStandardItemModel 的扩展解决方案。可以选择将哪些列设置为只读,将它们的列表传递给MyStandardItemModel.setReadOnly

      class MyStandardItemModel(QStandardItemModel):
      
          def __init__(self, parent=None, *arg, **kwargs):
              super().__init__(parent, *arg, **kwargs)
              self.__readonly_cols = []
      
          def flags(self, index: QtCore.QModelIndex) -> QtCore.Qt.ItemFlags:
                  if (index.column() in self.__readonly_cols):
                      return QtCore.Qt.ItemIsEnabled
                  else:
                      return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
      
          def setReadOnly(self, columns: [int]):
              for i in columns:
                  if i <= (self.columnCount() - 1) and i not in self.__readonly_cols:
                      self.__readonly_cols.append(i)
      
          def resetReadOnly(self):
              self.__readonly_cols = []
      

      希望对其他人有用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多