在Python中将`QTableWidget`整个列设置为只读

6 投票
3 回答
11251 浏览
提问于 2025-04-18 08:29

我想把表格中的一列设置为只读!我试过所有可能的标志组合,但都没有成功。

    item = QtGui.QTableWidgetItem()
    from operator import xor
    item.setFlags(xor(item.flags(),QtCore.Qt.ItemIsEditable))
    self.Table.setHorizontalHeaderItem(4, item)

我还尝试了 and not!=^ 这些操作符,但那一列的内容还是可以编辑。


更新

我觉得我之前理解错了!我以为当我把某一列的 HorizontalHeaderItem 设置为不可编辑时,这样在使用 insertRow() 等操作时,这一列的新项也会自动变为不可编辑。

其实我需要在插入新行后,对每一个新添加的项执行这些功能!

        tableWidget.insertRow(row+1)
        if  tableWidget is self.myTable:
            item = QtGui.QTableWidgetItem()
            item.setFlags(item.flags() != QtCore.Qt.ItemIsEditable)
            tableWidget.setItem(row+1, 4, item)

我觉得一个更好的(但更复杂的)解决方案是使用 setItemDelegateForColumn()QtGui.QItemDelegate() 来创建一个只读的自定义 QTableWidgetItem,这样每次插入或创建新行时都会添加这个项。


编辑

我试着使用上面提到的 setItemDelegateForColumn()QtGui.QItemDelegate(),但我收到了以下警告。

> python main.py
sys:1: RuntimeWarning: Invalid return value in function QItemDelegate.createEdit
or, expected PySide.QtGui.QWidget, got PySide.QtGui.QTableWidgetItem.

我的代码是这样的:

class QTableWidgetDisabledItem(QtGui.QItemDelegate):
    """
    """
    def __init__(self, parent):

        QtGui.QItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        item = QtGui.QTableWidgetItem()
        item.setFlags(item.flags() != QtCore.Qt.ItemIsEditable)
        return item

    def setEditorData(self, editor, index):
        editor.blockSignals(True)
        editor.setData(index, editor.text())
        editor.blockSignals(False)

    def setModelData(self, editor, model, index):
        model.setData(index, editor.text())

在主窗口中的代码:

    self.Size = QTableWidgetDisabledItem(self.MyTable)
    self.MyTable.setItemDelegateForColumn(4,self.Size)

不过这个主意还是不错的……

3 个回答

1

上面展示的解决方案可以简化为:

class MyDelegate(QtWidgets.QItemDelegate):

    def createEditor(self, *args):
        return None

table = QtWidgets.QTableWidget(2, 2)
table.setItemDelegateForColumn(MyDelegate())

这个解决方案和 ItemIsEditable 的方案不同,因为你仍然可以在这一列中选择和高亮显示项目。

4

试试看:

    flags != QtCore.Qt.ItemIsEditable
    item.setFlags(flags)

这次对我有效 :-)

补充说明:抱歉没有更详细的说明。其实你需要对想要的列中的每一项都进行操作,比如:

flags = Qt.ItemFlags()
flags != Qt.ItemIsEnabled

for r in range(rows):
    for c in range(columns):
        item = QTableWidgetItem('Row %s Column %s' % (r,c))
        if c == 2:
            item.setFlags(flags)
        table.setItem(r, c, item)

这会把第3列设置为只读,里面的项目都不能修改。希望这对你有帮助。

6

我用 QLineEditor 把它搞定了。

class QTableWidgetDisabledItem(QtGui.QItemDelegate):
    """
    Create a readOnly QTableWidgetItem
    """
    def __init__(self, parent):

        QtGui.QItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        item = QtGui.QLineEdit(parent)
        item.setReadOnly(True)
        #item.setEnabled(False)
        return item

    def setEditorData(self, editor, index):
        editor.blockSignals(True)
        editor.setText(index.model().data(index))
        editor.blockSignals(False)

    def setModelData(self, editor, model, index):
        model.setData(index, editor.text())

然后就可以像下面这样简单使用它。

self.Size = QTableWidgetDisabledItem(self.MyTable)
self.MyTable.setItemDelegateForColumn(4,self.Size)

撰写回答