5
votes

i want to set a column in my table to read-only! i tried all possible combinations of flags without success

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

i also tried and not, != and ^ operators but the column items are still editable


Update

I think i was misunderstanding this! i thought when i set the HorizontalHeaderItem at a column to be not editable, that will make all new items in that column to be automatically not editable, when using the operations like insertRow()

I had perform these function to each new added item after inserting new row!

        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)

I think a better (but more complex) solution is to use setItemDelegateForColumn() and QtGui.QItemDelegate() to create a read-only costum QTableWidgetItem which will be added each time a new row is inserted or created


Edit

Well i tried to use setItemDelegateForColumn() and QtGui.QItemDelegate() as mentioned above but i got the following Warning

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

My code for that was

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())

and in the MainWindow

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

It was good idea though ...

3
Did you try to remove Qt.ItemIsEnabled flag from all items of the column? - vahancho
@vahancho you mean with a loop ? - Ben Ishak
Yes, in the loop, for example. - vahancho

3 Answers

5
votes

I got it working using 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())

and then just simply use it as follow

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

try:

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

this worked for me last time :-)

EDIT: sorry for not being more detailed here. Of course you need to apply to every item in desired column, example:

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)

Will set column 3 to read-only items in that column. HTH

1
votes

The solution shown above can be simplified to:

class MyDelegate(QtWidgets.QItemDelegate):

    def createEditor(self, *args):
        return None

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

This solution differs from the ItemIsEditable solution in the sense that you can still select and highlight items in the column.