I am having problems with the Qt method to update a DataFrame if it has a specific element modified by the user in the GUI.
For example, when I run the following code, I get a 10 by 3 DataFrame with random values displayed. If I try to change any cell to value 400, I double click, type 400 and then press enter. When I print the DataFrame, the value is still the old value. I would like the DataFrame cell to update on user changing the value.
Many thanks!
import sys
import numpy as np
import pandas as pd
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QColor
from PyQt5.QtCore import pyqtSlot, Qt, QTimer
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(700, 100, 350, 380)
self.createTable()
self.layout = QVBoxLayout()
self.layout.addWidget(self.tableWidget)
self.button = QPushButton('Print DataFrame', self)
self.layout.addWidget(self.button)
self.setLayout(self.layout)
self.button.clicked.connect(self.print_my_df)
self.tableWidget.doubleClicked.connect(self.on_click_table)
self.show()
def createTable(self):
self.tableWidget = QTableWidget()
self.df_rows = 10
self.df_cols = 3
self.df = pd.DataFrame(np.random.randn(self.df_rows, self.df_cols))
self.tableWidget.setRowCount(self.df_rows)
self.tableWidget.setColumnCount(self.df_cols)
for i in range(self.df_rows):
for j in range(self.df_cols):
x = '{:.3f}'.format(self.df.iloc[i, j])
self.tableWidget.setItem(i, j, QTableWidgetItem(x))
@pyqtSlot()
def print_my_df(self):
print(self.df)
@pyqtSlot()
def on_click_table(self):
for currentQTableWidgetItem in self.tableWidget.selectedItems():
print((currentQTableWidgetItem.row(), currentQTableWidgetItem.column()))
self.print_my_df()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
QTableWidget
does not know about the existence of theDataFrame
so it is not updating it. We must update it for this we use thecellChanged
signal that gives us the row and column, then we use theitem()
method that returns theQTableWidgetItem
given the column and row, then we use thetext()
method ofQTableWidgetItem
.The data that is placed in the items in the user's edition can be of any type for example a text and this would generate an error since the
DataFrame
only accepts numerical values for this we must provide an input that validates for this we place aQLineEdit
with aQDoubleValidator
.Example: