In this PyQt5 article we are going to learn about PyQt5 QTableWidget Tutorial: Create a Dynamic Table, so PyQt5 is powerful Python module for creating graphical user interfaces (GUIs) for desktop applications. one of the most commonly used widgets in PyQt5 is QTableWidget. QTableWidget is class in PyQt5 that provides table view with sortable and editable cells. In this tutorial we are going to learn how to create dynamic table using PyQt5’s QTableWidget.
Before we start, make sure that you have installed PyQt5 on your machine. you can install it using pip by running the following command in your terminal:
1 |
pip install PyQt5 |
Now that we have PyQt5 installed, let’s create dynamic table using QTableWidget.
Step 1: Create basic PyQt5 application
The first step is to create a basic PyQt5 application. this can be done using following code:
1 2 3 4 5 6 7 |
import sys from PyQt5.QtWidgets import QApplication, QWidget app = QApplication(sys.argv) window = QWidget() window.show() sys.exit(app.exec_()) |
This code creates basic PyQt5 application with blank window. we will add QTableWidget to this window in the next step.
Run the complete code and this will be the result

Step 2: Add a QTableWidget to the application
Now that we have basic PyQt5 application, we can add QTableWidget to it. following code creates QTableWidget and adds it to the window:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import sys from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QVBoxLayout class App(QWidget): def __init__(self): super().__init__() self.title = 'GeeksCoders.com' self.left = 0 self.top = 0 self.width = 300 self.height = 200 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.createTable() self.layout = QVBoxLayout() self.layout.addWidget(self.tableWidget) self.setLayout(self.layout) self.show() def createTable(self): self.tableWidget = QTableWidget() self.tableWidget.setRowCount(4) self.tableWidget.setColumnCount(2) if __name__ == '__main__': app = QApplication(sys.argv) ex = App() sys.exit(app.exec_()) |
This code creates QTableWidget with 4 rows and 2 columns and adds it to the application’s layout. we also set the window’s title, size and position.
Run the complete code and this will be the result

Step 3: Populate the QTableWidget with data
Now that we have QTableWidget in our application, we can populate it with data. this code adds data to QTableWidget:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import sys from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QTableWidgetItem, QVBoxLayout class App(QWidget): def __init__(self): super().__init__() self.title = 'PyQt5 QTableWidget' self.left = 0 self.top = 0 self.width = 300 self.height = 200 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.createTable() self.populateTable() self.layout = QVBoxLayout() self.layout.addWidget(self.tableWidget) self.setLayout(self.layout) self.show() def createTable(self): self.tableWidget = QTableWidget() self.tableWidget.setRowCount(4) self.tableWidget.setColumnCount(2) def populateTable(self): data = [ ('John', 'Doe'), ('Geeks', 'Coders'), ('Joe', 'Bloggs'), ('Mary', 'Smith') ] row = 0 for item in data: col = 0 for val in item: cell = QTableWidgetItem(str(val)) self.tableWidget.setItem(row, col, cell) col += 1 row += 1 if __name__ == '__main__': app = QApplication(sys.argv) ex = App() sys.exit(app.exec_()) |
This code creates QTableWidget with 4 rows and 2 columns and populates it with data. the data is stored in list of tuples and we iterate through the list to add each tuple’s values to cell in the table. The QTableWidgetItem class is used to create the table cells, and the setItem() method is used to add the cells to the table.
Run the complete code and this will be the result.

Step 4: Make table dynamic
Now that we have a QTableWidget with data, we can make it dynamic. We can add rows and columns to the table as needed. The following code adds a button to the application that adds a row to the table when clicked:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
import sys from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QTableWidgetItem, QVBoxLayout, QPushButton class App(QWidget): def __init__(self): super().__init__() self.title = 'PyQt5 QTableWidget' self.left = 0 self.top = 0 self.width = 300 self.height = 200 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.createTable() self.populateTable() self.addBtn() self.layout = QVBoxLayout() self.layout.addWidget(self.tableWidget) self.layout.addWidget(self.button) self.setLayout(self.layout) self.show() def createTable(self): self.tableWidget = QTableWidget() self.tableWidget.setRowCount(4) self.tableWidget.setColumnCount(2) def populateTable(self): data = [ ('John', 'Doe'), ('Jane', 'Doe'), ('Joe', 'Bloggs'), ('Mary', 'Smith') ] row = 0 for item in data: col = 0 for val in item: cell = QTableWidgetItem(str(val)) self.tableWidget.setItem(row, col, cell) col += 1 row += 1 def addBtn(self): self.button = QPushButton('Add Row') self.button.clicked.connect(self.addRow) def addRow(self): numRows = self.tableWidget.rowCount() self.tableWidget.setRowCount(numRows + 1) if __name__ == '__main__': app = QApplication(sys.argv) ex = App() sys.exit(app.exec_()) |
The code adds button to application that adds row to the table when clicked. addBtn() method creates QPushButton and connects its clicked signal to addRow() method. addRow() method gets current number of rows in the table and increases it by one using the setRowCount() method. this makes the table one row taller, and the new row is added at bottom of the table.
You can now run the code and see that the table is dynamic. Clicking “Add Row” button will add new row to the table.