DEV Community

Hichem MG
Hichem MG

Posted on

2

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)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay