DEV Community

Hichem MG
Hichem MG

Posted on

How To Create a Python GUI To Write Data to a File With PyQt5

Creating graphical user interfaces (GUIs) for your Python applications can make them more user-friendly and accessible. PyQt5 is a powerful library that allows you to create professional-looking GUIs with ease.

In this tutorial, we'll build a simple application that lets users enter text and save it to a file. We'll cover everything from setting up the environment to enhancing the functionality of the application.

PyQt5 file writer app

Prerequisites

Before we begin, ensure you have the following:

  • Basic understanding of Python programming.
  • Python 3 installed on your system.
  • PyQt5 library installed (you can install it via pip).

To install PyQt5, run:

pip install PyQt5
Enter fullscreen mode Exit fullscreen mode

Step 1: Setting Up the Project Structure

First, create a project directory and navigate into it:

mkdir PyQt5FileWriter
cd PyQt5FileWriter
Enter fullscreen mode Exit fullscreen mode

Step 2: Creating the Main Application File

Create a new Python file named main.py in your project directory. This file will contain the main application logic.

Step 3: Importing Required Modules

In main.py, start by importing the necessary modules from PyQt5:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QFileDialog, QMessageBox
Enter fullscreen mode Exit fullscreen mode

Step 4: Designing the GUI

Next, we'll create a class for our main application window. This class will define the layout and components of our GUI.

Define the class and the constructor:

class FileWriterApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
Enter fullscreen mode Exit fullscreen mode

Initialize the UI components within initUI method:

def initUI(self):
    self.setWindowTitle('PyQt5 File Writer')
    self.setGeometry(100, 100, 400, 200)

    layout = QVBoxLayout()

    self.label = QLabel('Enter text to save to file:', self)
    layout.addWidget(self.label)

    self.textEdit = QLineEdit(self)
    layout.addWidget(self.textEdit)

    self.saveButton = QPushButton('Save to File', self)
    self.saveButton.clicked.connect(self.saveToFile)
    layout.addWidget(self.saveButton)

    self.setLayout(layout)
Enter fullscreen mode Exit fullscreen mode

Step 5: Implementing the Save Functionality

Implement the function to save text to a file:

def saveToFile(self):
    text = self.textEdit.text()
    if not text:
        QMessageBox.warning(self, 'Warning', 'Text field is empty')
        return

    options = QFileDialog.Options()
    fileName, _ = QFileDialog.getSaveFileName(self, 'Save File', '', 'Text Files (*.txt);;All Files (*)', options=options)
    if fileName:
        try:
            with open(fileName, 'w') as file:
                file.write(text)
            QMessageBox.information(self, 'Success', 'File saved successfully')
        except Exception as e:
            QMessageBox.critical(self, 'Error', f'Could not save file: {e}')
Enter fullscreen mode Exit fullscreen mode

Step 6: Running the Application

To run the application, add the following code at the end of main.py:

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = FileWriterApp()
    ex.show()
    sys.exit(app.exec_())
Enter fullscreen mode Exit fullscreen mode

Step 7: Enhancements and Best Practices

Input Validation

Enhance input validation by ensuring that the text is not empty or too long.

def saveToFile(self):
    text = self.textEdit.text()
    if not text:
        QMessageBox.warning(self, 'Warning', 'Text field is empty')
        return

    if len(text) > 1000:
        QMessageBox.warning(self, 'Warning', 'Text is too long')
        return

    options = QFileDialog.Options()
    fileName, _ = QFileDialog.getSaveFileName(self, 'Save File', '', 'Text Files (*.txt);;All Files (*)', options=options)
    if fileName:
        try:
            with open(fileName, 'w') as file:
                file.write(text)
            QMessageBox.information(self, 'Success', 'File saved successfully')
        except Exception as e:
            QMessageBox.critical(self, 'Error', f'Could not save file: {e}')
Enter fullscreen mode Exit fullscreen mode

File Overwrite Warning

Warn users if they are about to overwrite an existing file.

from pathlib import Path

def saveToFile(self):
    text = self.textEdit.text()
    if not text:
        QMessageBox.warning(self, 'Warning', 'Text field is empty')
        return

    options = QFileDialog.Options()
    fileName, _ = QFileDialog.getSaveFileName(self, 'Save File', '', 'Text Files (*.txt);;All Files (*)', options=options)
    if fileName:
        file_path = Path(fileName)
        if file_path.exists():
            reply = QMessageBox.question(self, 'File Exists', 'File already exists. Do you want to overwrite it?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.No:
                return

        try:
            with open(fileName, 'w') as file:
                file.write(text)
            QMessageBox.information(self, 'Success', 'File saved successfully')
        except Exception as e:
            QMessageBox.critical(self, 'Error', f'Could not save file: {e}')
Enter fullscreen mode Exit fullscreen mode

UI Improvements

Improve the UI by adding a menu bar and status bar.

from PyQt5.QtWidgets import QMainWindow, QAction, QStatusBar

class FileWriterApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

def initUI(self):
    self.setWindowTitle('PyQt5 File Writer')
    self.setGeometry(100, 100, 400, 200)

    centralWidget = QWidget()
    self.setCentralWidget(centralWidget)

    layout = QVBoxLayout()

    self.label = QLabel('Enter text to save to file:', self)
    layout.addWidget(self.label)

    self.textEdit = QLineEdit(self)
    layout.addWidget(self.textEdit)

    self.saveButton = QPushButton('Save to File', self)
    self.saveButton.clicked.connect(self.saveToFile)
    layout.addWidget(self.saveButton)

    centralWidget.setLayout(layout)

    menubar = self.menuBar()
    fileMenu = menubar.addMenu('File')

    saveAction = QAction('Save', self)
    saveAction.triggered.connect(self.saveToFile)
    fileMenu.addAction(saveAction)

    self.statusBar = QStatusBar()
    self.setStatusBar(self.statusBar)
Enter fullscreen mode Exit fullscreen mode

Complete Script

Here is the complete main.py script with all the enhancements and best practices included:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QFileDialog, QMessageBox, QStatusBar, QAction
from pathlib import Path

class FileWriterApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('PyQt5 File Writer')
        self.setGeometry(100, 100, 400, 200)

        centralWidget = QWidget()
        self.setCentralWidget(centralWidget)

        layout = QVBoxLayout()

        self.label = QLabel('Enter text to save to file:', self)
        layout.addWidget(self.label)

        self.textEdit = QLineEdit(self)
        layout.addWidget(self.textEdit)

        self.saveButton = QPushButton('Save to File', self)
        self.saveButton.clicked.connect(self.saveToFile)
        layout.addWidget(self.saveButton)

        centralWidget.setLayout(layout)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('File')

        saveAction = QAction('Save', self)
        saveAction.triggered.connect(self.saveToFile)
        fileMenu.addAction(saveAction)

        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)

    def saveToFile(self):
        text = self.textEdit.text()
        if not text:
            QMessageBox.warning(self, 'Warning', 'Text field is empty')
            return

        if len(text) > 1000:
            QMessageBox.warning(self, 'Warning', 'Text is too long')
            return

        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getSaveFileName(self, 'Save File', '', 'Text Files (*.txt);;All Files (*)', options=options)
        if fileName:
            file_path = Path(fileName)
            if file_path.exists():
                reply = QMessageBox.question(self, 'File Exists', 'File already exists. Do you want to overwrite it?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if reply == QMessageBox.No:
                    return

            try:
                with open(fileName, 'w') as file:
                    file.write(text)
                self.statusBar.showMessage('File saved successfully', 5000)
            except Exception as e:
                QMessageBox.critical(self, 'Error', f'Could not save file: {e}')
                self.statusBar.showMessage('Failed to save file', 5000)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = FileWriterApp()
    ex.show()
    sys.exit(app.exec_())
Enter fullscreen mode Exit fullscreen mode

Conclusion

You've now created a fully functional Python GUI application using PyQt5 that allows users to write data to a file.

This tutorial covered:

  • Setting up the project and creating the main application file.
  • Importing necessary modules and designing the GUI.
  • Handling user input and performing file operations.
  • Enhancements and best practices for a robust application.

By following this tutorial, you will gain a deeper understanding of building GUI applications with PyQt5.

Feel free to ask anything in the comments below. Happy coding!

Top comments (0)