Python Forum
Python QtableWidget get text of all cells and headers to dataframe
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python QtableWidget get text of all cells and headers to dataframe
#1
I would like to get the whole text in all cells and its headears from a Qtablewidget and write it to an dataframe (to export it later to an excel file). The table can be edited with new rows, columns and different headers. I found this solution,which works fine with numbers but with text the programm collapses.

The code is in python 3.6 and pyqt5.

Here is my adjusted code (in short without the whole editing options) so far:

import pandas as pd
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from pandas import DataFrame
import sys



data_single = {'hi': ['a', 'b'], 'hi2': ['d', 'c']}
tell_row=1

class TableWidget(QTableWidget):
    def __init__(self, df, parent=None):
        QTableWidget.__init__(self, parent)
        self.df = df
        nRows = len(self.df.index)
        nColumns = len(self.df.columns)
        self.setRowCount(nRows)
        self.setColumnCount(nColumns)

        for i in range(self.rowCount()):
            for j in range(self.columnCount()):
                x = self.df.iloc[i, j]
                self.setItem(i, j, QTableWidgetItem(x))

        self.cellChanged.connect(self.onCellChanged)

    #@pyqtSlot(int, int)
    def onCellChanged(self, row, column):
        text = self.item(row, column).text()
        number = float(text)
        self.df.set_value(row, column, number)


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(700, 100, 350, 380)
        df_rows = tell_row
        df_cols = 1
        df =pd.DataFrame(data_single)
        self.tableWidget = TableWidget(df, self)

        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)

    @pyqtSlot()
    def print_my_df(self):
        some_df =self.tableWidget.df
        print(some_df)

        fn, _ = QFileDialog.getSaveFileName(self, 'Speichern unter', None, 'Excel Dateien (.xlsx);;Alle Dateien()')
        if fn != '':
            if QFileInfo(fn).suffix() == "": fn += '.xlsx'
        df = DataFrame(some_df)
        df.to_excel(fn, sheet_name='Ergebnisse', index=False)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())
Reply
#2
you can save it as csv (change delimiter if you need)

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import pandas as pd
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from pandas import DataFrame
import sys
import csv
 
 
data_single = {'hi': ['a', 'b'], 'hi2': ['d', 'c']}
tell_row=1
 
class TableWidget(QTableWidget):
    def __init__(self, df, parent=None):
        QTableWidget.__init__(self, parent)
        self.df = df
        nRows = len(self.df.index)
        nColumns = len(self.df.columns)
        self.setRowCount(nRows)
        self.setColumnCount(nColumns)
 
        for i in range(self.rowCount()):
            for j in range(self.columnCount()):
                x = self.df.iloc[i, j]
                self.setItem(i, j, QTableWidgetItem(x))
 
        self.cellChanged.connect(self.onCellChanged)
 
    #@pyqtSlot(int, int)
    def onCellChanged(self, row, column):
        text = self.item(row, column).text()
        number = float(text)
        self.df.set_value(row, column, number)
 
 
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
 
    def initUI(self):
        self.setGeometry(700, 100, 350, 380)
        df_rows = tell_row
        df_cols = 1
        df =pd.DataFrame(data_single)
        self.tableWidget = TableWidget(df, self)
 
        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.writeCsv)
 
    @pyqtSlot()
    def print_my_df(self):
        some_df =self.tableWidget.df
        print(some_df)
 
        fn, _ = QFileDialog.getSaveFileName(self, 'Speichern unter', None, 'Excel Dateien (.xlsx);;Alle Dateien()')
        if fn != '':
            if QFileInfo(fn).suffix() == "": fn += '.xlsx'
        df = DataFrame(some_df)
        df.to_excel(fn, sheet_name='Ergebnisse', index=False)

    def writeCsv(self):
        path, _ = QFileDialog.getSaveFileName(self, 'Save File', QDir.homePath() + "/export.csv", "CSV Files(*.csv *.txt)")
        if path:
            with open(path, 'w') as stream:
                print("saving", path)
                writer = csv.writer(stream, delimiter='\t')
                headers = []
                for column in range(self.tableWidget.columnCount()):
                    header = self.tableWidget.horizontalHeaderItem(column)
                    if header is not None:
                         headers.append(header.text())
                    else:
                        headers.append("Column " + str(column))
                writer.writerow(headers)
                for row in range(self.tableWidget.rowCount()):
                    rowdata = []
                    for column in range(self.tableWidget.columnCount()):
                        item = self.tableWidget.item(row, column)
                        if item is not None:
                            rowdata.append(item.text())
                        else:
                            rowdata.append('')
                    writer.writerow(rowdata)
 
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())
Reply
#3
thanks fors your reply unfurtunally the code still has the same bug. I am only able to change the cells to a different number and save it. change it to letters or words makes the window collaps.
Reply
#4
change

number = float(text)

to

number = str(text)

why do you use pandas ?

or you can do

    def onCellChanged(self, row, column):
        text = self.item(row, column).text()
        number = QTableWidgetItem(text)
        self.setItem(row, column, number)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Checking for a recognized text in a Dataframe KDE 0 1,542 Aug-31-2021, 11:19 PM
Last Post: KDE
  Python - Merge existing cells of Excel file created with xlsxwriter manonB 0 3,715 Mar-10-2021, 02:17 PM
Last Post: manonB
  newbie: loop, modify dataframe cells expat_th 5 3,698 Mar-03-2020, 09:05 PM
Last Post: jefsummers
  Is there a Python text mining script to classify text with multiple classifications? Endearment 0 1,841 Oct-21-2019, 07:50 PM
Last Post: Endearment
  Sum product multiple Dataframes based on column headers. Lastwizzle 0 3,829 May-21-2019, 04:05 PM
Last Post: Lastwizzle
  Auto-headers disable in importing CSV files zealjeung 3 3,081 Jul-08-2018, 12:41 PM
Last Post: volcano63
  Add column headers to dataframe chisox721 5 8,771 May-20-2018, 12:31 AM
Last Post: volcano63
  Read CSV Files with multiple headers into Python DataFrame UGuntupalli 12 26,783 Jan-26-2017, 03:07 PM
Last Post: UGuntupalli

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020