PyQt QToolBar

Summary: in this tutorial, you’ll learn how to use the PyQt QToolBar class to create toolbar widgets.

Introduction to the PyQt QToolBar class

A toolbar is a movable panel that contains a set of controls. To create a toolbar, you use the QToolBar class:

The following creates a new toolbar using the QToolBar class and adds it to the main window using the addToolBar() method of the QMainWindowObject:

toolbar = QToolBar('Main ToolBar')
self.addToolBar(toolbar)Code language: Python (python)

The setIconSize() method of the QToolBar object allows you to set the icon size of the icons that appear on the toolbar.

For example, you can set the size of the icons to (16,16). To do so, you pass a QSize object to the setIconSize() method like this:

toolbar.setIconSize(QSize(16, 16))Code language: Python (python)

Typically, you add buttons to the toolbar using the addAction() method:

toolbar.addAction(my_action)Code language: Python (python)

To separate between groups of buttons on the toolbar, you use the addSeparator() method:

toolbar.addSeparator()Code language: Python (python)

Besides buttons, you can add widgets to the toolbar using the addWidget() method.

A toolbar can be movable between toolbar areas of the main window by default. To make the toolbar fixed in a particular area, you pass False to the setMovable() method of the QToolBar object.

To set an area for the toolbar, you can use the setAllowedArea() method. The allowed areas are top, bottom, left, and right.

Using the PyQt QToolBar class to create a toolbar

We’ll continue the text editor program from the QMenu tutorial by creating a toolbar widget:

The following shows the complete program:

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


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.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()
        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 save_document(self):
        # save the currently openned file
        if (self.path):
            return self.path.write_text(self.text_edit.toPlainText())

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

        if not filename:
            return

        self.path = Path(filename)
        self.path.write_text(self.text_edit.toPlainText())
        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()


if __name__ == '__main__':
    try:
        import ctypes
        myappid = 'mycompany.myproduct.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 toolbar part)

First, create a new toolbar object using the QToolBar class and add it to the main window using the addToolBar() method.

toolbar = QToolBar('Main ToolBar')
self.addToolBar(toolbar)Code language: Python (python)

Next, set the icon size of the icons on the toolbar to (16,16):

toolbar.setIconSize(QSize(16, 16))Code language: Python (python)

Then, add new, save, and open actions to the toolbar. Also, add a separator using the addSeparator() method:

toolbar.addAction(new_action)
toolbar.addAction(save_action)
toolbar.addAction(open_action)
toolbar.addSeparator()Code language: Python (python)

After that, add undo and redo actions to the toolbar and another separator:

toolbar.addAction(undo_action)
toolbar.addAction(redo_action)
toolbar.addSeparator()Code language: Python (python)

Finally, add the exit action:

toolbar.addAction(exit_action)Code language: Python (python)

Summary

  • Use the QToolBar class to create a new toolbar.
  • Use the addToolBar() method to add a toolbar to the main window.
  • Use the addAction() method to add an item to the toolbar.
  • Use the addSeparator() method to add a separator to the buttons.
Did you find this tutorial helpful ?