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 секунд после запуска программы.
- Добавить постоянный виджет, отображающий количество символов в строке состояния.
- Показывать сообщение после сохранения файла.
Вот полная программа:
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() вызывается всякий раз при сохранении файла.