PyQt QStatusBar

Summary: in this tutorial, you’ll learn how to use the PyQt QStatusBar class to create status bar widgets.

Introduction to the PyQt QStatusBar class

The QStatusBar class allows you to create a status bar widget. The status bar widget is useful for presenting status information.

Typically, you’ll use the statusBar() method of the QMainWindow object to create a status bar for the main window:

self.status_bar = self.statusBar()Code language: Python (python)

The statusBar() method returns the status bar of the main window. If the status bar doesn’t exist, the function creates and returns an empty status bar.

So if you assign the status bar to the self.status_bar variable, you can use the variable later in other methods of the class.

Or you can directly call the self.statusBar() method to get the QStatusBar object and call its method.

To show a message on the status bar, you use the showMessage() method of the QStatusBar object.

showMessage(text,timeout=0)Code language: Python (python)

By default, the showMessage() message will display the text until you call the clearMessage() or the showMessage() method again.

The timeout specifies the number of milliseconds the message will display. The timeout defaults to zero which displays the text permanently.

Each status on the status has one of the following categories:

  • Temporary – briefly occupies most of the status bar. For example, statuses that explain tool tip texts or menu entries.
  • Normal – occupies only part of the status bar. For example, the status for displaying the page and line number.
  • Permanent – is always shown. For example, a message that shows a Caps Lock indicator status.

In addition to showing a message, you can add a widget to the status bar using the addWidget() method:

addWidget(widget[, stretch=0])Code language: Python (python)

To hide a widget on the status bar, you use the removeWidget() method. Once you hide a widget, you can display it again using the addWidget() method.

The status bar locates the widget added by the addWidget() method at the far left. If you call the showMessage() method, the message will hide the widget.

To add a permanent widget to the status bar, you use addPermanentWidget() method:

addPermanentWidget(widget[, stretch=0])Code language: Python (python)

The method adds the widget to the status bar and changes the parent of the widget to the QStatusBar object if the widget is not a child of the QStatusBar object.

The QStatusBar locates the permanent widget to the far right of the status bar.

PyQt QStatusBar example

We’ll continue the text editor program from the QToolBar tutorial. We’ll do the following with the status bar:

  • Show a Ready message that displays in 5 seconds when the program launches.
  • Add a permanent widget that displays the number of characters on the status bar.
  • Show a message when the file has been saved.

Here’s the complete program:

import sys
from pathlib import Path
from PyQt6.QtWidgets import QApplication, QMainWindow, QTextEdit, QFileDialog, QMessageBox, QToolBar, QLabel
from PyQt6.QtGui import QIcon, QAction
from PyQt6.QtCore import QSize


class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowIcon(QIcon('./assets/editor.png'))
        self.setGeometry(100, 100, 500, 300)

        self.title = 'Editor'
        self.filters = 'Text Files (*.txt)'

        self.set_title()

        self.path = None

        self.text_edit = QTextEdit(self)
        self.text_edit.textChanged.connect(self.text_changed)
        self.setCentralWidget(self.text_edit)        

        menu_bar = self.menuBar()

        file_menu = menu_bar.addMenu('&File')
        edit_menu = menu_bar.addMenu('&Edit')
        help_menu = menu_bar.addMenu('&Help')

        # new menu item
        new_action = QAction(QIcon('./assets/new.png'), '&New', self)
        new_action.setStatusTip('Create a new document')
        new_action.setShortcut('Ctrl+N')
        new_action.triggered.connect(self.new_document)
        file_menu.addAction(new_action)

        # open menu item
        open_action = QAction(QIcon('./assets/open.png'), '&Open...', self)
        open_action.triggered.connect(self.open_document)
        open_action.setStatusTip('Open a document')
        open_action.setShortcut('Ctrl+O')
        file_menu.addAction(open_action)

        # save menu item
        save_action = QAction(QIcon('./assets/save.png'), '&Save', self)
        save_action.setStatusTip('Save the document')
        save_action.setShortcut('Ctrl+S')
        save_action.triggered.connect(self.save_document)
        file_menu.addAction(save_action)

        file_menu.addSeparator()

        # exit menu item
        exit_action = QAction(QIcon('./assets/exit.png'), '&Exit', self)
        exit_action.setStatusTip('Exit')
        exit_action.setShortcut('Alt+F4')
        exit_action.triggered.connect(self.quit)
        file_menu.addAction(exit_action)

        # edit menu
        undo_action = QAction(QIcon('./assets/undo.png'), '&Undo', self)
        undo_action.setStatusTip('Undo')
        undo_action.setShortcut('Ctrl+Z')
        undo_action.triggered.connect(self.text_edit.undo)
        edit_menu.addAction(undo_action)

        redo_action = QAction(QIcon('./assets/redo.png'), '&Redo', self)
        redo_action.setStatusTip('Redo')
        redo_action.setShortcut('Ctrl+Y')
        redo_action.triggered.connect(self.text_edit.redo)
        edit_menu.addAction(redo_action)

        about_action = QAction(QIcon('./assets/about.png'), 'About', self)
        help_menu.addAction(about_action)
        about_action.setStatusTip('About')
        about_action.setShortcut('F1')

        # toolbar
        toolbar = QToolBar('Main ToolBar')
        self.addToolBar(toolbar)
        toolbar.setIconSize(QSize(16, 16))

        toolbar.addAction(new_action)
        toolbar.addAction(save_action)
        toolbar.addAction(open_action)
        toolbar.addSeparator()

        toolbar.addAction(undo_action)
        toolbar.addAction(redo_action)
        toolbar.addSeparator()

        toolbar.addAction(exit_action)

        # status bar
        self.status_bar = self.statusBar()
        
        # display the a message in 5 seconds
        self.status_bar.showMessage('Ready', 5000)

        # add a permanent widget to the status bar
        self.character_count = QLabel("Length: 0")
        self.status_bar.addPermanentWidget(self.character_count)

        self.show()

    def set_title(self, filename=None):
        title = f"{filename if filename else 'Untitled'} - {self.title}"
        self.setWindowTitle(title)

    def confirm_save(self):
        if not self.text_edit.document().isModified():
            return True

        message = f"Do you want to save changes to {self.path if self.path else 'Untitled'}?"
        MsgBoxBtn = QMessageBox.StandardButton
        MsgBoxBtn = MsgBoxBtn.Save | MsgBoxBtn.Discard | MsgBoxBtn.Cancel

        button = QMessageBox.question(
            self, self.title, message, buttons=MsgBoxBtn
        )

        if button == MsgBoxBtn.Cancel:
            return False

        if button == MsgBoxBtn.Save:
            self.save_document()

        return True

    def new_document(self):
        if self.confirm_save():
            self.text_edit.clear()
            self.set_title()

    def write_file(self):
        self.path.write_text(self.text_edit.toPlainText())
        self.statusBar().showMessage('The file has been saved...', 3000)

    def save_document(self):
        # save the currently openned file
        if (self.path):
            return self.write_file()

        # save a new file
        filename, _ = QFileDialog.getSaveFileName(
            self, 'Save File', filter=self.filters
        )

        if not filename:
            return

        self.path = Path(filename)
        self.write_file()
        self.set_title(filename)

    def open_document(self):
        filename, _ = QFileDialog.getOpenFileName(self, filter=self.filters)
        if filename:
            self.path = Path(filename)
            self.text_edit.setText(self.path.read_text())
            self.set_title(filename)

    def quit(self):
        if self.confirm_save():
            self.destroy()

    def text_changed(self):
        text = self.text_edit.toPlainText()
        self.character_count.setText(f'Length: {len(text)}')


if __name__ == '__main__':
    try:
        # show the app icon on the taskbar
        import ctypes
        myappid = 'yourcompany.yourproduct.subproduct.version'
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
    finally:
        app = QApplication(sys.argv)
        window = MainWindow()
        sys.exit(app.exec())Code language: Python (python)

How it works. (We’ll focus on the status bar part)

First, call the statusBar() method to create the status bar for the main window:

self.status_bar = self.statusBar()Code language: Python (python)

Next, show the ‘Ready’ message in five seconds using the showMessage() method:

self.status_bar.showMessage('Ready', 5000)Code language: Python (python)

Then, add a permanent widget to the status bar using the addPermanentWidget() method:

self.character_count = QLabel("Length: 0")
self.status_bar.addPermanentWidget(self.character_count)Code language: Python (python)

The QLabel widget displays the number of characters of the QTextEdit widget. By default, it shows zero characters.

After that, connect the textChanged signal with the self.text_changed slot to update the character count:

self.text_edit.textChanged.connect(self.text_changed)Code language: Python (python)

and you need to define the text_changed method:

def text_changed(self):
        text = self.text_edit.toPlainText()
        self.character_count.setText(f'Length: {len(text)}')Code language: Python (python)

Finally, define the write_file() method that saves text to a file and displays a message indicating that the file has been saved for three seconds:

def write_file(self):
        self.path.write_text(self.text_edit.toPlainText())
        self.statusBar().showMessage('The file has been saved...', 3000)Code language: Python (python)

The write_file() method is called whenever the file is saved.

Summary

  • Qt uses QStatusBar class to create a status bar widget.
  • Use the statusBar() method to get a status bar of the main window.
  • Use the showMessage() to display a message on the status bar.
  • Use the addWidget() or addPermanentWidget() method to add a widget to the status bar.
Did you find this tutorial helpful ?