Thursday, May 9, 2024

Building a Simple Spreadsheet App with PyQt6

 Introduction:

In this blog post, we will explore how to create a simple spreadsheet application using PyQt6, a Python framework for creating graphical user interfaces (GUIs). Spreadsheets are powerful tools commonly used for data organization, calculation, and analysis. Our goal is to build a basic spreadsheet application with features like adding and deleting rows and columns, editing cell contents, and printing selected items.


Setting Up the Environment: Before we dive into the code, ensure you have Python installed on your system. Additionally, you'll need to install PyQt6, which you can do using pip:

pip install PyQt6

Creating the User Interface: We'll start by creating a graphical user interface (GUI) for our spreadsheet application. We'll use PyQt6's QWidget and QTableWidget classes to build the interface. The GUI will consist of a main window with buttons for adding/deleting rows and columns, a table widget to display the spreadsheet data, and a print button to print selected items.

Adding Functionality: Once the GUI is set up, we'll implement functionality for adding and deleting rows and columns, editing cell contents, and printing selected items. We'll connect PyQt6 signals to appropriate slots to handle user interactions, such as button clicks and context menu actions.

Exploring Key Features:

  • Adding Rows and Columns: Users can add new rows and columns to the spreadsheet using dedicated buttons.
  • Deleting Rows and Columns: Rows and columns can be deleted by selecting them and clicking the delete button.
  • Editing Column Names: Users can edit column names by right-clicking on the column header and selecting the "Edit Column Name" option from the context menu.
  • Printing Selected Items: Users can select one or more cells and print their contents.

Conclusion: In this blog post, we've demonstrated how to create a simple spreadsheet application using PyQt6. While our application provides basic functionality, there's plenty of room for further enhancements, such as data validation, formula support, and additional formatting options. By building upon the foundation laid out here, you can create more advanced spreadsheet applications tailored to your specific needs.

Final Thoughts: Creating a spreadsheet application from scratch can be a rewarding experience, and PyQt6 provides a powerful toolkit for building intuitive and feature-rich GUIs. Whether you're building a personal productivity tool or a business application, PyQt6's flexibility and ease of use make it an excellent choice for developing desktop applications in Python.

Here is the code:

import sys
from PyQt6.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QHBoxLayout, QVBoxLayout, QWidget, QPushButton, QMenu, QInputDialog
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QIcon
class EmptyTableWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Empty Table Widget')

        self.addButton = QPushButton('', self)
        self.addButton.clicked.connect(self.addRow)
        self.addButton.setIcon(QIcon("addrow.jpg"))

        self.delButton = QPushButton('', self)
        self.delButton.clicked.connect(self.delRow)
        self.delButton.setIcon(QIcon("delrow.jpg"))

        self.addColumnButton = QPushButton('', self)
        self.addColumnButton.clicked.connect(self.addColumn)
        self.addColumnButton.setIcon(QIcon("addcolumn.jpg"))

        self.delColumnButton = QPushButton('', self)
        self.delColumnButton.clicked.connect(self.delColumn)
        self.delColumnButton.setIcon(QIcon("delcolumn.jpg"))

        self.prnButton = QPushButton('Print', self)
        self.prnButton.clicked.connect(self.printSelectedItem)
        
        self.columnCount = 0

        self.tableWidget = QTableWidget()
        self.tableWidget.setColumnCount(0)  # Set the number of columns
        #self.tableWidget.setHorizontalHeaderLabels(['Column 1', 'Column 2', 'Column 3'])  # Set column headers
        layout = QHBoxLayout()
        layout.addWidget(self.addButton)
        layout.addWidget(self.delButton)
        layout.addWidget(self.addColumnButton)
        layout.addWidget(self.delColumnButton)
        layout.addWidget(self.prnButton)
        self.layout = QVBoxLayout()
        self.layout.addLayout(layout)
        self.layout.addWidget(self.tableWidget)
        self.setLayout(self.layout)

        self.tableWidget.horizontalHeader().setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.tableWidget.horizontalHeader().customContextMenuRequested.connect(self.showContextMenu)
    def delColumn(self):
        selectedColumn = self.tableWidget.currentColumn()
        if selectedColumn >= 0:
            self.tableWidget.removeColumn(selectedColumn)
            self.columnCount -= 1
    def addColumn(self):
         
        self.columnCount += 1
        self.tableWidget.setColumnCount(self.columnCount)
        for i in range(self.columnCount):
            if self.tableWidget.horizontalHeaderItem(i) is None:
                defaultName = chr(65 + i)  # Convert integer to corresponding ASCII character ('A' for 0, 'B' for 1, etc.)
                self.tableWidget.setHorizontalHeaderItem(i, QTableWidgetItem(f'{defaultName}'))

    def delRow(self):
        selectedRow = self.tableWidget.currentRow()
        if selectedRow >= 0:
            self.tableWidget.removeRow(selectedRow)
    def addRow(self):
        currentRowCount = self.tableWidget.rowCount()
        self.tableWidget.setRowCount(currentRowCount + 1)
        for col in range(self.tableWidget.columnCount()):
            newItem = QTableWidgetItem("")
            self.tableWidget.setItem(currentRowCount, col, newItem)

    def showContextMenu(self, pos):
        menu = QMenu(self)
        editAction = menu.addAction("Edit Column Name")
        action = menu.exec(self.tableWidget.mapToGlobal(pos))
        if action == editAction:
            column = self.tableWidget.horizontalHeader().logicalIndexAt(pos)
            newName, okPressed = QInputDialog.getText(self, "Enter New Name", f"Column {column+1}")
            if okPressed:
                self.tableWidget.setHorizontalHeaderItem(column, QTableWidgetItem(newName))
    def printSelectedItem(self):
        selected_item = self.tableWidget.selectedItems()
        if selected_item:
            for item in selected_item:
                print("Selected Item:", item.text())
        else:
            print("No item selected.")

def main():
    app = QApplication(sys.argv)
    window = EmptyTableWidget()
    window.show()
    sys.exit(app.exec())

if __name__ == '__main__':
    main()

No comments:

Post a Comment