首页 > 解决方案 > 是否可以使 QTableView 中的列标签可编辑?

问题描述

我一直在用 QTabelView 学习 QAbstractTabelModel。我能够使用 Flags 和 setData 来使项目可编辑。但是,我不知道如何使列可编辑。换句话说,我想通过双击并提供一个新名称来更改列的名称。如果可能的话,你能给一些例子+代码注释吗?在这里,我有一个使用 QTabelView 的简单应用程序,它使用模型显示一些数据。

我将不胜感激任何建议

import sys
from PyQt5 import QtWidgets, QtCore, QtGui


class MyTableModel(QtCore.QAbstractTableModel):
    def __init__(self, data=[[]], headers=[], parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)


        self.__data = data
        self.__headers = headers

    # Headers
    def headerData(self, section, orientation, role):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:


                if section < len(self.__headers):
                    return self.__headers[section]
                else:
                    return "Temporary"

            else:
                return section + 1


    def rowCount(self, parent):
        return len(self.__data)

    def columnCount(self, parent):
        return len(self.__data[0])


    def data(self, index, role):

        if role == QtCore.Qt.EditRole:
            row = index.row()
            column = index.column()
            return self.__data[row][column]

        # Displaying data
        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            value = self.__data[row][column]
            return value


    def flags(self, index):
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled

    # Making cells editable==================================
    def setData(self, index, value, role=QtCore.Qt.EditRole):
        if role == QtCore.Qt.EditRole:
            row = index.row()
            column = index.column()
            new_element = value
            if new_element:
                self.__data[row][column] = new_element
                return True

            else:
                return False

        # =============================================================================#
        # INSERTING & REMOVING  ITEMS

    def insertRows(self, position, rows, parent=QtCore.QModelIndex()):

        self.beginInsertRows(parent, position, position + rows - 1)

        for i in range(rows):
            defaultValues = [i for i in range(1, 4)]
            self.__data.insert(position, defaultValues)

        self.endInsertRows()
        return True


    def removeRows(self, position, rows, parent=QtCore.QModelIndex()):

        self.beginRemoveRows(parent, position, position + rows - 1)  # Старт процесс удаления
        # Removing here
        for i in range(rows):
            value = self.__data[position]
            self.__data.remove(value)

        self.endRemoveRows()

        return True


    def insertColumns(self, position, columns, parent=QtCore.QModelIndex()):
        self.beginInsertColumns(parent, position, position + columns - 1)
        """self.beginInsertColumns(index, first, last)"""
            # index - parent
        # first - position
        # last - position + columns - 1 = view ожидает 0 образный элемент

        rowCount = len(self.__data)
        for i in range(columns):

            for j in range(rowCount):  # Преребираем Строки
                self.__data[j].insert(position, "new cell")

        self.endInsertColumns()
        return True
    # removing columns from view ================================================================
    def removeColumns(self, position, columns, parent=QtCore.QModelIndex()):
        self.beginRemoveColumns(parent, position, position + columns - 1)  # Старт процесс удаления
        # Removing here

        rowCount = len(self.__data)

        for i in range(columns):
            for j in range(rowCount):
                print(self.__data[j])
                value = self.__data[j][position]

                self.__data[j].remove(value)

        self.endRemoveColumns()

        return True


#  My Window -----------------------------------------------------------------------------------
class MyWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()


        data = [
            ["value", "value", "value"],
            ["value", "value", "value"]
        ]

        headers = ["col1", "col2", "col3", ]



        self.TableView = QtWidgets.QTableView()
        self.TableView.show()


        self.model = MyTableModel(data, headers)

            #inserting rows
        #self.model.insertRows(0, 1)


        # self.model.removeRows(0, 1)

        #self.model.insertColumns(0, 1)


        #self.model.removeColumns(0, 1)
        self.TableView.setModel(self.model)





app = QtWidgets.QApplication(sys.argv)
win = MyWindow()
sys.exit(app.exec_())

在此处输入图像描述

标签: pythonpyqt5

解决方案


您可以通过 更改单个标题数据setHeaderData()

然后只需连接到sectionDoubleClicked()信号并使用输入对话框从用户那里获取新标题。

由于您使用的是 QAbstractItemModel 的子类,因此您也必须覆盖相应的方法。

class MyTableModel(QtCore.QAbstractTableModel):
    # ...

    def setHeaderData(self, section, orientation, value, role=QtCore.Qt.DisplayRole):
        if 0 < section < len(self.__headers) and orientation == QtCore.Qt.Horizontal:
            self.__headers[section] = value
            return True
        return QtCore.QAbstractTableModel.setHeaderData(self, section,
            orientation, value, role)

class MyWindow(QtWidgets.QWidget):
    def __init__(self):
        # ...
        self.TableView.horizontalHeader().sectionDoubleClicked.connect(self.renameSection)


    def renameSection(self, index):
        oldTitle = self.model.headerData(
            index, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole)

        newTitle, accepted = QtWidgets.QInputDialog.getText(
            self, 'Change column title', oldTitle)

        if accepted and oldTitle != newTitle:
            self.model.setHeaderData(
                index, QtCore.Qt.Horizontal, newTitle, QtCore.Qt.DisplayRole)

推荐阅读