2

I have QTableWidget which is non editable.(i had setup noEditTriggers while creating Ui file). I want to make particular cell editable from each row. how i can get this done?

I looked into several answers on SO and other platforms but didn't get anything working for me.

currently I am using this piece of code. it doesnt give an error but i still could not edit that cell value.

self.item = QTableWidgetItem('Hi')
flags = self.item.flags()
flags ^= QtCore.Qt.ItemIsEditable
self.item.setFlags(flags)
self.table.setItem(row, column, self.item)

EDIT::

Snippet to get the table view

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Vi_py123
  • 73
  • 1
  • 9

2 Answers2

2

Using the same fundament for the @musicamante answer is to create a delegate that only returns one editor in the specific column, the advantage is that you don't need to subclassify QTableWidget and the logic can be used in other types of views:

class Delegate(QtWidgets.QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        if index.column() == 2:
            return super(Delegate, self).createEditor(parent, option, index)
delegate = Delegate(self.table)
self.table.setItemDelegate(delegate)

Update:

If you want the cells with NN to be editable then you must return the editor when it meets that condition: index.data() == "NN"

import random
import sys

from PyQt5 import QtWidgets


class Delegate(QtWidgets.QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        if index.data() == "NN":
            return super(Delegate, self).createEditor(parent, option, index)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    texts = ["Hello", "Stack", "Overflow", "NN"]

    table = QtWidgets.QTableWidget(10, 5)
    delegate = Delegate(table)
    table.setItemDelegate(delegate)

    for i in range(table.rowCount()):
        for j in range(table.columnCount()):
            text = random.choice(texts)
            it = QtWidgets.QTableWidgetItem(text)
            table.setItem(i, j, it)

    table.resize(640, 480)
    table.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thank you for this. but it seems i still dont have what i need. i have edited a question and added a snippet of my table format. i need to edit highlighted cells only. how can i implement your logic? I am running a loop over row and column and i would have row and column index for that particular cell to be editable. thanks again! – Vi_py123 Feb 23 '20 at 10:16
  • @VirenKheni change `if index.column() == 2:` for example to `if index.column() == 2 and index.row() == 2:` – S. Nick Feb 23 '20 at 10:25
  • yes, but this particular piece of code above is not serving what i need. it is still keeping that cell non editable. i tried what you just said. @S.Nick – Vi_py123 Feb 23 '20 at 10:30
  • @VirenKheni An image without explanation does not help at all. Do you want cell 0x3 and 3x3 not to be editable or that cells with "NN" are not editable? – eyllanesc Feb 23 '20 at 20:10
  • i want only those cells to be editable which has 'NN' rest everything stays readonly. – Vi_py123 Feb 24 '20 at 07:15
0

You could set the flags for each item, while leaving the default edit triggers, but this is not very good approach, since you could have a very large table, some items could be changed/added/removed and you might forget to set/reset the flags.

A better approach could be to override the edit() method, and execute the default implementation (which creates the item editor and starts the editing) by manually setting the edit trigger.
This requires to leave the default edit triggers (or at least one trigger method) set.

class TableWidget(QtWidgets.QTableWidget):
    def edit(self, index, trigger, event):
        # editing is allowed only for the third column
        if index.column() != 2:
            trigger = self.NoEditTriggers
        return super().edit(index, trigger, event)
musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Thank you for this. but it seems i still dont have what i need. i have edited a question and added a snippet of my table format. i need to edit highlighted cells only. how can i implement your logic? I am running a loop over row and column and i would have row and column index for that particular cell to be editable. thanks again! – Vi_py123 Feb 23 '20 at 10:16
  • Can'y you just check the column *and* the row? `if index.column() != 3 or index.row() not in (0, 3): trigger = self.NoEditTriggers` – musicamante Feb 23 '20 at 14:22