QTableview checkitems, получить значение из соответствующего второго столбца - PullRequest
1 голос
/ 01 августа 2020

У меня два вопроса относительно QTableView.

  1. Как сделать QTable редактируемым только для значения второго столбца и только для чтения для первого столбца?

  2. Как получить индекс отмеченного элемента, чтобы можно было получить значение второго столбца, соответствующего отмеченному элементу?

    from PyQt5 import QtWidgets, QtGui
    
    class MyWidget(QtWidgets.QWidget):
    
        def __init__(self, parent=None):
            super().__init__(parent=parent)
    
            # selected items
            self.selected = []
            self.no       = []
    
            self.tableModel = QtGui.QStandardItemModel(self)
            self.tableModel.itemChanged.connect(self.itemChanged)
            # 
            item1 = QtGui.QStandardItem("file#1")
            item1.setCheckable(True)
            no1 = QtGui.QStandardItem("5.0")
            self.tableModel.appendRow([item1, no1])
            # 
            item2 = QtGui.QStandardItem("file#2")
            item2.setCheckable(True)
            no2 = QtGui.QStandardItem("23.0")
            self.tableModel.appendRow([item2, no2])
    
            self.mainLayout = QtWidgets.QVBoxLayout()
            self.setLayout(self.mainLayout)
    
            self.tableView = QtWidgets.QTableView()
            self.tableView.setModel(self.tableModel)
            self.mainLayout.addWidget(self.tableView)
    
            "First Question"
            """How to make table only editable second column, not firts:
               ex. can edit 23.0 or 5.0, but read only file names?
            """        
    
        def itemChanged(self, item):
            if item.checkState() != 0:
                if not item.text() in self.selected:
                    self.selected.append(item.text())
            else:
                if item.text() in self.selected:
                    self.selected.remove(item.text())
    
            print(self.selected)
    
            "Second Question"
            """How to get item checked index and to get the second column value:
               ex. file#2 has 23.0?
            """
    
            self.no.append(second column value) ****?
            print(self.no)
    
    def main():
        app = QtWidgets.QApplication([])
    
        mytable = MyWidget()
        mytable.show()
        app.exec_()
    
    if __name__ == "__main__":
        main()
    

Ответы [ 2 ]

2 голосов
/ 01 августа 2020

Как сделать QTable доступным для редактирования только для второго значения столбца и только для чтения для первого столбца?

Существует несколько решений, позволяющих сделать элементы всего столбца доступными только для чтения / редактирования.

  • модифицируйте флаги, нет необходимости реализовывать настраиваемую модель, как это предлагается PyThagoras ответы , поскольку модель QStandardItemModel позволяет изменять их:

    # To make them editable:
    item.setEditable(True)
    # or
    # item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
    
    # To make them readonly:
    item.setEditable(False)
    # or
    # item.setFlags(item.flags() & ~QtCore.Qt.ItemIsEditable)
    
  • Используйте редактор делегата, поскольку модель QStandardItemModel редактируется по умолчанию, поэтому достаточно sh установить, что столбец 0 не редактируется, и для этого вам не следует создавать редактор. :

    class ReadOnlyDelegate(QtWidgets.QStyledItemDelegate):
        def createEditor(self, parent, option, index):
            return
    
    delegate = ReadOnlyDelegate(self.tableView)
    self.tableView.setItemDelegateForColumn(0, delegate)
    

Я предпочитаю второй вариант, поскольку по умолчанию он устанавливает, что первый столбец доступен только для чтения.

Как получить индекс отмеченного элемента, чтобы вы могли получить значение второго столбца, соответствующего отмеченному элементу?

Общий метод c - получить доступ к отцу, а затем сын, который находится в той же строке, но во втором столбце:

parent_item = item.parent()
if parent_item is not None:
    second_item = parent_item.child(item.row(), 1)
else:
    second_item = item.model().item(item.row(), 1)
print(second_item.text())

Но в вашем случае это можно упростить до:

second_item = self.tableModel.item(item.row(), 1)
print(second_item.text())
0 голосов
/ 01 августа 2020

Это два отдельных вопроса. Я считаю, что вам следует задать их отдельно и соответствующим образом изменить свой вопрос.

Для вашего первого вопроса: как сделать столбец READ_ONLY?

Для этого вы должны определить ваш собственный QAbstractTableModel class для определения метода с именем flags. Эти флаги позволят вам изменять свойства ячеек по вашему желанию. Затем вам нужно передать свой новый QAbstractTableModel в QTableView и установить его как новую модель (это похоже на бэкэнд QTableView)

from PyQt5.QtCore import Qt, QAbstractTableModel
from PyQt5.QtWidgets import QTableView, QApplication


class ParametersTableModel(QAbstractTableModel):

    def __init__(self):
        super(ParametersTableModel, self).__init__()
        self.headerText = ["Parameter 1", "Parameter 2"]
        self.data = [[1, 2], [1, 2]]

    def rowCount(self, parent=None):
        return len(self.data)

    def columnCount(self, parent=None):
        return len(self.headerText)

    def headerData(self, col, orientation, role):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                return self.headerText[col]

    def data(self, index, role):
        if role == Qt.DisplayRole or role == Qt.EditRole:
            return self.data[index.row()][index.column()]

    def flags(self, index):
        if not index.isValid():
            return None
        else:
            if index.column() == 1:
                return Qt.ItemIsEnabled | Qt.ItemIsSelectable
            else:
                return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable


def main():
    app = QApplication([])
    tableModel = ParametersTableModel()
    tableView = QTableView()
    tableView.setModel(tableModel)
    tableView.show()
    app.exec_()


if __name__ == "__main__":
    main()

Вы всегда можете проверить документацию Qt для более глубокого понимания. QTableView , QAbstractTableModel

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...