PyQt QStatusBar в Python — виджет строки состояния

Класс PyQt QStatusBar в Python позволяет создать виджет строки состояния.

Что такое PyQt QStatusBar

Обычно для создания строки состояния главного окна используется метод statusBar() объекта QMainWindow:

self.status_bar = self.statusBar()

Метод statusBar() возвращает строку состояния главного окна. Если строка состояния не существует, функция создает и возвращает пустую строку состояния.

Таким образом, если вы назначите строку состояния переменной self.status_bar, вы сможете использовать эту переменную позже в других методах класса.

Или вы можете напрямую вызвать метод self.statusBar(), чтобы получить объект QStatusBar и вызвать его метод.

Чтобы отобразить сообщение в строке состояния, используйте метод showMessage() объекта QStatusBar.

showMessage(text,timeout=0)

По умолчанию сообщение showMessage() будет отображать текст до тех пор, пока вы снова не вызовете метод clearMessage() или showMessage().

Тайм-аут определяет количество миллисекунд, в течение которых сообщение будет отображаться. timeout по умолчанию равен нулю, что означает, что текст отображается постоянно.

Каждый статус имеет одну из следующих категорий:

  • Temporary – ненадолго занимает большую часть строки состояния. Например, статусы, поясняющие тексты подсказок или пунктов меню.
  • Normal – занимает только часть строки состояния. Например, статус отображения номера страницы и строки.
  • Permanent – отображается всегда. Например, сообщение, показывающее состояние индикатора Caps Lock.

Помимо отображения сообщения, вы можете добавить виджет в строку состояния с помощью метода addWidget():

addWidget(widget[, stretch=0])

Чтобы скрыть виджет в строке состояния, используйте метод removeWidget(). После того, как вы скрыли виджет, вы можете снова отобразить его с помощью метода addWidget().

Строка состояния находит виджет, добавленный методом addWidget(), в самом левом углу. Если вы вызовете метод showMessage(), сообщение скроет виджет.

Чтобы добавить постоянный виджет в строку состояния, используйте метод addPermanentWidget():

addPermanentWidget(widget[, stretch=0])

Метод добавляет виджет в строку состояния и изменяет родительский элемент виджета на объект QStatusBar, если виджет не является дочерним элементом объекта QStatusBar.

QStatusBar размещает постоянный виджет в правой части строки состояния.

Пример PyQt QStatusBar

Продолжим программу текстового редактора из учебника QToolBar. Сделаем следующие действия со строкой состояния:

  • Показывать сообщение о готовности, которое появится через 5 секунд после запуска программы.
  • Добавить постоянный виджет, отображающий количество символов в строке состояния.
  • Показывать сообщение после сохранения файла.

Пример с PyQt QStatusBar

Вот полная программа:

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())

Как это работает (Мы сосредоточимся на части строки состояния).

  • Сначала вызовите метод statusBar(), чтобы создать строку состояния для главного окна:
self.status_bar = self.statusBar()
  • Затем через пять секунд покажите сообщение «Готово» с помощью метода showMessage():
self.status_bar.showMessage('Ready', 5000)
  • Затем добавьте постоянный виджет в строку состояния с помощью метода addPermanentWidget():
self.character_count = QLabel("Length: 0")
self.status_bar.addPermanentWidget(self.character_count)

Виджет QLabel отображает количество символов виджета QTextEdit. По умолчанию он отображает ноль символов.

  • После этого соедините сигнал textChanged со слотом self.text_changed для обновления количества символов:
self.text_edit.textChanged.connect(self.text_changed)
  • И вам нужно определить метод text_changed:
def text_changed(self):
        text = self.text_edit.toPlainText()
        self.character_count.setText(f'Length: {len(text)}')
  • Наконец, определите метод write_file(), который сохраняет текст в файл и отображает сообщение о том, что файл был сохранен в течение трех секунд:
def write_file(self):
        self.path.write_text(self.text_edit.toPlainText())
        self.statusBar().showMessage('The file has been saved...', 3000)

Метод write_file() вызывается всякий раз при сохранении файла.

Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *