python - 是否可以使 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_())
解决方案
您可以通过 更改单个标题数据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)
推荐阅读
- java - java.lang.NoClassDefFoundError: com/google/appengine/api/urlfetch/HTTPMethod
- django - Django搜索中的部分匹配
- python - 在 Visual Studio 2017 中使用 Pybind11 for Python 构建 CPP 时出现编译错误
- symfony - 通过 filezilla 将 symfony 4.2 项目部署到共享主机
- html - 无法将高分辨率图像放在宽度为 33.3333% 的内联 div 中
- r - 满足某些条件时如何有效地返回 1m 条记录中的所有列名
- c# - 如何创建指定数据库类型的 DbContext 实例
- sql-server - 将函数应用于列中的一行
- tensorflow - 跨平台的 TensorFlow 结果
- php - 通过使用php将表单中的值添加到表列中的现有值来更新数据库中的值的问题