26

i have the following code defining the gui of my app

class Ui (object):
    def setupUi():
        self.tableName = QtGui.QTableWidget(self.layoutWidget_20)
        self.tableName.setObjectName(_fromUtf8("twHistoricoDisciplinas"))
        self.tableName.setColumnCount(4)
        self.tableName.setRowCount(3)

and the following code in my app

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        self.ui = Ui()
        self.ui.setupUi(self)
        self.createtable()

    #creating a tw cell
    def cell(self,var=""):
            item = QtGui.QTableWidgetItem()
            item.setText(var)
            return item

    def createtable(self):
         rows = self.tableName.rowCount()
         columns = self.tableName.columnCount()
         for i in range(rows):
             for j in range(columns):
                 item = self.cell("text")
                 self.ui.tableName.setItem(i, j, item)

I want to be able to add new rows and columns and edit them but i want to lock some of the cells. ( i already have code that expand the table ) how can i make some cells read only while keeping the others read write? i found this link How to make a column in QTableWidget read only? with a solution for the problem in C++, is python solution similar ?

EDIT: Removed the answer from the post and pasted as an answer

Community
  • 1
  • 1
Rafael Rotelok
  • 1,102
  • 1
  • 14
  • 26
  • 2
    There is usually very few differencies between the c++ and the python code with Qt. You just have to adjust the syntax and this piece of code will work like a charm. – madjar Oct 11 '11 at 14:50
  • 2
    @madjar ...it really did work like a charm :), i just needed to find where were declared the flags, i´m new to python and qt, it takes some time to get used to it – Rafael Rotelok Oct 11 '11 at 17:04

6 Answers6

32

I played a little with the code and read some more documentation the answer to the problem is

def createtable(self):
     rows = self.tableName.rowCount()
     columns = self.tableName.columnCount()
     for i in range(rows):
         for j in range(columns):
             item = self.cell("text")
             # execute the line below to every item you need locked
             item.setFlags(QtCore.Qt.ItemIsEnabled)
             self.ui.tableName.setItem(i, j, item)

The solution is the line "item.setFlags(QtCore.Qt.ItemIsEnabled)", you use it to set the cell property QtCore.Qt.ItemIsEnabled to disabled, so you can't select or edit the cell

You can change a number of other properties this way at runtime as per documentarion on http://doc.qt.io/archives/qt-4.8/qt.html under the section Qt::ItemFlag

as mentioned in a comment by Sven on the second answer to this question, if you have a static number of rows and columns in your QTableWidgetItem you can select the properties of the cells with Qtdesigner if you use it to create the screens for your application

Rafael Rotelok
  • 1,102
  • 1
  • 14
  • 26
25

The editing status of a QTableWidgetItem is never entered when there are no Edit Triggers:

self.tableName.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)

Sven-Eric Krüger
  • 1,277
  • 12
  • 19
21

Like Sven Krüger's answer, you can also use this methods for PyQt5:

self.tableWidget.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
ozcanyarimdunya
  • 2,324
  • 1
  • 18
  • 21
6

If you want the UI to look the same (have it still selectable, and turn blue, but just not editable) I found QtCore.Qt.ItemIsEditable gave good results.

item = QtWidgets.QTableWidgetItem()
item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
self.table_widget.setItem(row, column, item)
Adam Sirrelle
  • 357
  • 8
  • 18
  • This answer is the most correct. You shouldn't set the flag like the other answers, where you remove all the other flags. At the same time, you can add " ^ Qt.ItemIsSelectable" or " ^ Qt.ItemIsEnabled" to make the item unselectable or disable it. – Feng Jiang Apr 18 '23 at 20:27
3

For PyQt6, it's the same as @ozcanyarimdunya but with the enum EditTrigger:

self.tableWidget.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 24 '22 at 09:36
0

if you want to make the whole table is not editable try this:

for row in range(self.tableName.rowCount()):
    for col in range(self.tableName.columnCount()):
        self.tableName.item(row,col).setFlags(Qt.ItemFlag.ItemIsEditable)
Koedlt
  • 4,286
  • 8
  • 15
  • 33
abodi
  • 1
  • 2