0

My problem is how to make the newly inserted row editable when I click button to insert row. I set flags to QTableWidgetItem with Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable, but only created a non-editable row.

As I searched out, there are 3 ways to make cell, row, column editable using :

  1. delegate
  2. flag
  3. using QTableview with model, role

For me, using 'flag' looks easy, but only got a non-editable row... Or should I use QTableView rather than QTableWidget to make cell, row or column editable? I hope to listen to many ideas and appreciate it.

I added one QTableWidget and one QPushButton on QTDesigner and the rest code is as belows :

# -*- coding: utf-8 -*-

import sys 

import pandas as pd
import numpy as np

from PyQt5.QtWidgets import *

from PyQt5.QtCore import *
from PyQt5.QtGui import *


from ex052_ui_table_cell_editable_q  import Ui_MainWindow 


class MainWindow(QMainWindow): 
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        
        self.df_data = pd.DataFrame([[1, 9, 2], [1, 0, -1], [3, 5, 2], [3, 3, 2], [5, 8, 9],], columns=["A", "B", "C"])
        self.df_data["CRUD"] = "R"                

        self.ui.table_acct_books.setColumnCount(len(self.df_data.columns))
        self.ui.table_acct_books.setRowCount(len(self.df_data.index))
        
        len_index = len(self.df_data.index)
        len_cols = len(self.df_data.columns)
        for i in range(len_index):
            for j in range(len_cols):
                table_item = QTableWidgetItem(str(self.df_data.iloc[i, j]))
                table_item.setFlags(table_item.flags() & ~Qt.ItemIsEditable)
                self.ui.table_acct_books.setItem(i, j, table_item)  
                
        self.ui.table_acct_books.setColumnHidden(3, True)        
        # self.ui.table_acct_books.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.ui.table_acct_books.setAlternatingRowColors(True)
        
        self.ui.btn_row_add.clicked.connect(self.btn_row_add_clicked)
        self.ui.btn_save.clicked.connect(self.btn_save_clicked)
     
     
        
    def btn_row_add_clicked(self):
        row_count = self.ui.table_acct_books.rowCount()
        self.ui.table_acct_books.insertRow(row_count)        
       
        item = QTableWidgetItem("editable")
        item.setFlags(item.flags() | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)        
        
        len_cols = len(self.df_data.columns)
        for j in range(len_cols):
            self.ui.table_acct_books.setItem(row_count, j, item)
            
        self.ui.table_acct_books.setItem(row_count, j, QTableWidgetItem("C"))


    def btn_save_clicked(self):        
        number_of_rows = self.ui.table_acct_books.rowCount()
        number_of_columns = self.ui.table_acct_books.columnCount()
        
        for i in range(number_of_rows):                            
            item_crud = str(self.ui.table_acct_books.item(i, 3).text())            
            
            for j in range(number_of_columns):                
                item = self.ui.table_acct_books.item(i, j)
                if item is None:
                    item_text = ""
                    item = QTableWidgetItem("")
                else:
                    item_text = item.text()
                                
                    if j == 3 and item_crud != 'R':
                        item = QTableWidgetItem("R")
                    
                item.setFlags(item.flags() & ~Qt.ItemIsEditable)
                self.ui.table_acct_books.setItem(i, j, item)                  


if __name__ == "__main__":    
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

the UI source is created by QTDesigner as followings :

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ex052_ui_table_cell_editable_q.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 539)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.table_acct_books = QtWidgets.QTableWidget(self.centralwidget)
        self.table_acct_books.setGeometry(QtCore.QRect(20, 20, 761, 331))
        self.table_acct_books.setObjectName("table_acct_books")
        self.table_acct_books.setColumnCount(0)
        self.table_acct_books.setRowCount(0)
        self.btn_row_add = QtWidgets.QPushButton(self.centralwidget)
        self.btn_row_add.setGeometry(QtCore.QRect(20, 370, 321, 23))
        self.btn_row_add.setObjectName("btn_row_add")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btn_row_add.setText(_translate("MainWindow", "Add Row"))
Joywins
  • 21
  • 4
  • You are making it not editable, since you're disabling *all* ways to start editing with `setEditTriggers(QAbstractItemView.NoEditTriggers)`. Remove that line and read the [documentation](https://doc.qt.io/qt-5/qabstractitemview.html#editTriggers-prop) more carefully to understand how to use that enum. – musicamante Feb 16 '22 at 15:27
  • @musicamante If I remove 'setEditTriggers(QAbstractItemView.NoEditTriggers)', all the rows are editable. I only click a button and hope to set the newly added row to editable status. Thanks and I will review your mentioned link more. – Joywins Feb 16 '22 at 17:18
  • Then just unset the `ItemIsEditable` flag for previously added items: `table_acct_book_item.setFlags(table_acct_book_item.flags() & ~Qt.ItemIsEditable)`. – musicamante Feb 16 '22 at 18:02
  • @musicamante I also expected your idea highly would work, but it is still non-editable. So I'm going to plan B which make another QTableWidget for input when I click button to add row, but I am still wonder why it does not work. – Joywins Feb 17 '22 at 00:36
  • 1
    If it's still not editable it means that you didn't remove the `setEditTriggers` line. Edit triggers are mandatory if you want to make ***any*** (as in "some", not "all") item editable, then you have to unset the `ItemIsEditable` flag for all items that should not be editable as explained above. – musicamante Feb 17 '22 at 00:51
  • @musicamante Yes, it works now. I have tried to follow your idea to comment setEditTriggers and unset ItemIsEditable. Thanks a lot for your help to make me go next step!!! – Joywins Feb 17 '22 at 15:08

0 Answers0