ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов
Скачать 7.92 Mb.
|
• WidgetWithChildrenShortcut — 3 — комбинация доступна, если фокус имеет роди- тельский компонент или любой дочерний компонент; • WindowShortcut — 1 — комбинация доступна, если окно, в котором расположен компонент, является активным; • ApplicationShortcut — 2 — комбинация доступна, если любое окно приложения является активным; setToolTip(<Текст>) — задает текст всплывающей подсказки; toolTip() — возвращает текст всплывающей подсказки; setWhatsThis(<Текст>) — задает текст справки; whatsThis() — возвращает текст справки; setStatusTip(<Текст>) — задает текст, который будет отображаться в строке состояния при наведении указателя мыши на пункт меню; statusTip() — возвращает текст для строки состояния; setCheckable(<Флаг>) — если в качестве параметра указано значение True , действие является переключателем, который может находиться в двух состояниях: установленном и неустановленном; isCheckable() — возвращает значение True , если действие является переключателем, и False — в противном случае; setChecked(<Флаг>) — если в качестве параметра указано значение True , действие- переключатель будет находиться в установленном состоянии. Метод является слотом; isChecked() — возвращает значение True , если действие-переключатель находится в установленном состоянии, и False — в противном случае; setDisabled(<Флаг>) — если в качестве параметра указано значение True , действие ста- нет недоступным. Значение False делает действие вновь доступным. Метод является слотом; 660 Часть II. Библиотека PyQt 5 setEnabled(<Флаг>) — если в качестве параметра указано значение False , действие станет недоступным. Значение True делает действие вновь доступным. Метод является слотом; isEnabled() — возвращает значение True , если действие доступно, и False — в против- ном случае; setVisible(<Флаг>) — если в качестве параметра указано значение False , действие будет скрыто. Значение True вновь выводит действие на экран. Метод является слотом; isVisible() — возвращает значение False , если действие скрыто, и True — в противном случае; setMenu( — устанавливает вложенное меню; menu() — возвращает ссылку на вложенное меню (экземпляр класса QMenu ) или значение None , если вложенного меню нет; setFont( — устанавливает шрифт для текста; font() — возвращает экземпляр класса QFont с текущими параметрами шрифта; setAutoRepeat(<Флаг>) — если в качестве параметра указано значение True (значение по умолчанию), действие будет повторяться, пока удерживается нажатой комбинация «горячих» клавиш; setPriority(<Приоритет>) — задает приоритет действия. В качестве параметра указы- ваются атрибуты: LowPriority (низкий), NormalPriority (нормальный) или HighPriority (высокий) класса QAction ; priority() — возвращает текущий приоритет действия; setData(<Данные>) — позволяет сохранить пользовательские данные любого типа в объ- екте действия; data() — возвращает пользовательские данные, сохраненные ранее с помощью метода setData() , или значение None ; setActionGroup( — добавляет действие в указанную группу; actionGroup() — возвращает ссылку на группу (экземпляр класса QActionGroup ) или значение None ; showStatusText([widget=None]) — отправляет событие QEvent.StatusTip указанному в параметре widget компоненту и возвращает значение True , если событие успешно отправлено. Если компонент не указан, событие посылается родителю действия. Чтобы обработать событие, необходимо наследовать класс компонента и переопреде- лить метод event(self, . При событии QEvent.StatusTip через параметр доступен экземпляр класса QStatusTipEvent . Получить текст для строки состоя- ния можно через метод tip() объекта события. Вот пример обработки события в классе, наследующем класс QLabel : def event(self, e): if e.type() == QtCore.QEvent.StatusTip: self.setText(e.tip()) return True return QtWidgets.QLabel.event(self, e) hover() — посылает сигнал hovered() . Метод является слотом; Глава 27. Создание SDI- и MDI-приложений 661 toggle() — производит изменение состояния переключателя на противоположное. Метод является слотом; trigger() — посылает сигнал triggered() . Метод является слотом. Класс QAction поддерживает следующие сигналы: changed() — генерируется при изменении действия; hovered() — генерируется при наведении указателя мыши на объект действия; toggled(<Состояние>) — генерируется при изменении состояния переключателя. Внутри обработчика через параметр доступно текущее состояние в виде логической величины; triggered(<Состояние переключателя>) — генерируется при выборе пункта меню, нажа- тии кнопки на панели инструментов, нажатии комбинации клавиш или вызове метода trigger() . В параметре доступно текущее состояние действия-переключателя в виде логической величины — для обычных действий значение параметра всегда равно False 27.2.5. Объединение переключателей в группу Класс QActionGroup позволяет объединить несколько действий-переключателей в группу. По умолчанию внутри группы может быть установлен только один переключатель — при попытке установить другой переключатель ранее установленный будет автоматически сброшен. Иерархия наследования для этого класса выглядит так: QObject — QActionGroup Конструктор класса QActionGroup имеет следующий формат: <Объект> = QActionGroup( В параметре указывается ссылка на родительский компонент или значение None После создания объекта группы он может быть указан в качестве родителя при создании объектов действия — в этом случае действие автоматически добавляется в группу. Класс QActionGroup поддерживает следующие основные методы: addAction() — добавляет объект действия в группу. Метод возвращает экземпляр класса QAction . Форматы метода: addAction( removeAction( — удаляет объект действия из группы; actions() — возвращает список с экземплярами класса QAction , которые были добавле- ны в группу, или пустой список; checkedAction() — возвращает ссылку (экземпляр класса QAction ) на установленный переключатель внутри группы при использовании эксклюзивного режима или значение None ; setExclusive(<Флаг>) — если в качестве параметра указано значение False , внутри группы может быть установлено произвольное количество действий-переключателей. Значение True возвращает эксклюзивный режим, при котором только одно действие- переключатель может быть установлено. Метод является слотом; setDisabled(<Флаг>) — если в качестве параметра указано значение True , все действия в группе станут недоступными. Значение False делает действия вновь доступными. Ме- тод является слотом; 662 Часть II. Библиотека PyQt 5 setEnabled(<Флаг>) — если в качестве параметра указано значение False , все действия в группе станут недоступными. Значение True делает действия вновь доступными. Ме- тод является слотом; isEnabled() — возвращает значение True , если действия в группе доступны, и False — в противном случае; setVisible(<Флаг>) — если в качестве параметра указано значение False , все действия в группе будут скрыты. Значение True вновь выводит действия на экран. Метод является слотом; isVisible() — возвращает значение False , если действия группы скрыты, и True — в противном случае. Класс QActionGroup поддерживает сигналы: hovered( — генерируется при наведении указателя мыши на объект действия внутри группы. Внутри обработчика через параметр доступна ссылка на этот объект действия; triggered( — генерируется при выборе пункта меню, нажатии кнопки на панели инструментов или комбинации клавиш. Внутри обработчика через параметр дос- тупна ссылка на этот объект действия. 27.3. Панели инструментов Панели инструментов предназначены для отображения часто используемых команд. До- бавить панель инструментов в главное окно позволяют методы addToolBar() и insertToolBar() класса QMainWindow . Один из форматов метода addToolBar() позволяет ука- зать область, к которой изначально прикреплена панель. По умолчанию с помощью мыши пользователь может переместить панель в другую область окна или отобразить панель в отдельном окне. Ограничить перечень областей, к которым можно прикрепить панель, позволяет метод setAllowedAreas() класса QToolBar , а запретить отображение панели в от- дельном окне — метод setFloatable() 27.3.1. Класс QToolBar Класс QToolBar реализует панель инструментов, которую можно перемещать с помощью мыши. Иерархия наследования для него такова: (QObject, QPaintDevice) — QWidget — QToolBar Форматы конструктора класса QToolBar : <Объект> = QToolBar([parent=None]) <Объект> = QToolBar(<Название>[, parent=None]) В параметре parent указывается ссылка на родительский компонент, а в параметре <Назва- ние> — название панели, которое отображается в контекстном меню при щелчке правой кнопкой мыши в области меню, области панелей инструментов или на заголовке прикреп- ляемых панелей. С помощью контекстного меню можно скрыть или отобразить панель ин- струментов. Класс QToolBar наследует все методы базовых классов и поддерживает следующие собст- венные методы (здесь приведены только основные — полный их список можно найти на странице https://doc.qt.io/qt-5/qtoolbar.html): Глава 27. Создание SDI- и MDI-приложений 663 addAction() — добавляет действие на панель инструментов. Форматы метода: addAction( addSeparator() — добавляет разделитель и возвращает представляющий его экземпляр класса QAction ; insertSeparator( — добавляет разделитель перед указанным действием и возвращает представляющий разделитель экземпляр класса QAction ; addWidget( — позволяет добавить компонент (например, раскрывающийся список). Метод возвращает представляющий компонент экземпляр класса QAction ; insertWidget( — добавляет компонент перед указанным действи- ем и возвращает представляющий компонент экземпляр класса QAction ; widgetForAction( — возвращает ссылку на компонент (экземпляр класса QWidget ), который связан с указанным действием; clear() — удаляет все действия из панели инструментов; setOrientation(<Ориентация>) — задает ориентацию панели в виде следующих атрибу- тов класса QtCore.Qt : • Horizontal — 1 — горизонтальная (значение по умолчанию); • Vertical — 2 — вертикальная; setAllowedAreas(<Области>) — задает области, к которым можно прикрепить панель инструментов. В качестве параметра указываются атрибуты (или их комбинация через оператор | ) LeftToolBarArea (слева), RightToolBarArea (справа), TopToolBarArea (свер- ху), BottomToolBarArea (снизу) или AllToolBarAreas (все области) класса QtCore.Qt ; setMovable(<Флаг>) — если в качестве параметра указано значение False , будет невоз- можно перемещать панель с помощью мыши. Значение True вновь разрешает перемеще- ние панели; isMovable() — возвращает значение True , если панель можно перемещать с помощью мыши, и False — в противном случае; setFloatable(<Флаг>) — если в качестве параметра указано значение False , панель нельзя будет вынести в отдельное окно. Значение True вновь разрешает выносить панель в окно; isFloatable() — возвращает значение True , если панель можно вынести в отдельное окно, и False — в противном случае; isFloating() — возвращает значение True , если панель в данный момент вынесена в отдельное окно, и False — в противном случае; setToolButtonStyle(<Стиль>) — задает стиль кнопок на панели инструментов. Метод является слотом. В качестве параметра указываются следующие атрибуты класса QtCore.Qt : • ToolButtonIconOnly — 0 — отображается только значок; • ToolButtonTextOnly — 1 — отображается только текст; 664 Часть II. Библиотека PyQt 5 • ToolButtonTextBesideIcon — 2 — текст отображается справа от значка; • ToolButtonTextUnderIcon — 3 — текст отображается под значком; • ToolButtonFollowStyle — 4 — зависит от используемого стиля; toolButtonStyle() — возвращает стиль кнопок на панели инструментов; setIconSize( — задает размеры значков. Метод является слотом; iconSize() — возвращает размеры значков (экземпляр класса QSize ); toggleViewAction() — возвращает объект действия (экземпляр класса QAction ), с по- мощью которого можно скрыть или отобразить панель. Класс QToolBar поддерживает следующие сигналы (здесь приведены только основные — полный их список можно найти на странице https://doc.qt.io/qt-5/qtoolbar.html): actionTriggered( — генерируется при нажатии кнопки на панели. Внутри обработчика через параметр доступно действие, связанное с этой кнопкой; visibilityChanged(<Флаг>) — генерируется при изменении видимости панели. Внутри обработчика через параметр доступно значение True , если панель видима, и False — если скрыта; topLevelChanged(<Флаг>) — генерируется при изменении состояния панели. Внутри об- работчика через параметр доступно значение True , если панель вынесена в отдельном окне, и False — если прикреплена к области. 27.3.2. Класс QToolButton При добавлении действия на панель инструментов автоматически создается кнопка, пред- ставляемая классом QToolButton . Получить ссылку на кнопку позволяет метод widgetForAction() класса QToolBar . Иерархия наследования для класса QToolButton выгля- дит так: (QObject, QPaintDevice) — QWidget — QAbstractButton — QToolButton Конструктор класса QToolButton имеет следующий формат: <Объект> = QToolButton([parent=None]) В параметре parent указывается ссылка на родительский компонент. Класс QToolButton , помимо методов базовых классов, поддерживает следующие методы (здесь приведены только основные — полный их список можно найти на странице https://doc.qt.io/qt-5/qtoolbutton.html): setDefaultAction( — связывает объект действия с кнопкой. Метод является слотом; defaultAction() — возвращает ссылку на объект действия (экземпляр класса QAction ), связанный с кнопкой; setToolButtonStyle(<Стиль>) — задает стиль кнопки. Метод является слотом. До- пустимые значения параметра приведены в описании метода setToolButtonStyle() (см. разд. 27.3.1); toolButtonStyle() — возвращает стиль кнопки; setMenu( — добавляет к кнопке меню; Глава 27. Создание SDI- и MDI-приложений 665 menu() — возвращает ссылку на меню (экземпляр класса QMenu ), добавленное к кнопке, или значение None ; showMenu() — отображает меню, связанное с кнопкой. Метод является слотом; setPopupMode(<Режим>) — задает режим отображения меню, связанного с кнопкой. В качестве параметра указываются следующие атрибуты класса QToolButton : • DelayedPopup — 0 — меню отображается при удержании кнопки, нажатой в течение некоторого промежутка времени; • MenuButtonPopup — 1 — справа от кнопки отображается кнопка со стрелкой, нажатие которой приводит к немедленному открытию меню; • InstantPopup — 2 — нажатие кнопки приводит к немедленному открытию меню. Сигнал triggered() при этом не генерируется; popupMode() — возвращает режим отображения меню, связанного с кнопкой; setArrowType(<Тип значка>) — позволяет вместо стандартного значка действия устано- вить значок в виде стрелки, указывающей в заданном направлении. В качестве парамет- ра задаются атрибуты NoArrow (значение по умолчанию), UpArrow , DownArrow , LeftArrow или RightArrow класса QtCore.Qt ; setAutoRaise(<Флаг>) — если в качестве параметра указано значение False , кнопка будет отображаться с рамкой. По умолчанию кнопка сливается с фоном, а при наведе- нии указателя мыши становится выпуклой. Класс QToolButton поддерживает сигнал triggered( , который генерируется при нажатии кнопки или комбинации клавиш, а также при выборе пункта в связанном меню. Внутри обработчика через параметр доступно соответствующее действие. 27.4. Прикрепляемые панели Если возможностей панелей инструментов недостаточно, и необходимо вывести на экран компоненты, занимающие много места (например, таблицу или иерархический список), можно воспользоваться прикрепляемыми панелями. Прикрепляемые панели реализуются с помощью класса QDockWidget Его иерархия наследования выглядит так: (QObject, QPaintDevice) — QWidget — QDockWidget Форматы конструктора класса QDockWidget : <Объект> = QDockWidget([parent=None][, flags=0]) <Объект> = QDockWidget(<Название>[, parent=None][, flags=0]) В параметре <Название> задается название панели, которое отображается в заголовке панели и в контекстном меню при щелчке правой кнопкой мыши в области меню, области панелей инструментов или на заголовке прикрепляемых панелей. С помощью контекстного меню можно скрыть или отобразить прикрепляемую панель. В параметре parent указывается ссылка на родительское окно. Доступные значения параметра flags мы рассматривали в разд. 18.2. Класс QDockWidget наследует все методы базовых классов и поддерживает следующие до- полнительные методы (здесь приведены только интересующие нас — полный их список можно найти на странице https://doc.qt.io/qt-5/qdockwidget.html): 666 Часть II. Библиотека PyQt 5 setWidget( — устанавливает компонент, который будет отображаться на при- крепляемой панели; widget() — возвращает ссылку на компонент, расположенный на панели; setTitleBarWidget( — позволяет указать пользовательский компонент, ото- бражаемый в заголовке панели; titleBarWidget() — возвращает ссылку на пользовательский компонент, расположен- ный в заголовке панели, или значение None , если компонент не был установлен; setAllowedAreas(<Области>) — задает области, к которым можно прикрепить панель. В качестве параметра указываются атрибуты (или их комбинация через оператор | ) LeftDockWidgetArea (слева), RightDockWidgetArea (справа), TopDockWidgetArea (сверху), BottomDockWidgetArea (снизу) или AllDockWidgetAreas (все области) класса QtCore.Qt ; setFloating(<Флаг>) — если в качестве параметра указано значение True , панель ото- бразится в отдельном окне, а если указано значение False , она будет прикреплена к ка- кой-либо области; isFloating() — возвращает значение True , если панель отображается в отдельном окне, и False — в противном случае; setFeatures(<Свойства>) — устанавливает свойства панели. В качестве параметра ука- зывается комбинация (через оператор | ) следующих атрибутов класса QDockWidget : • DockWidgetClosable — панель можно закрыть; • DockWidgetMovable — панель можно перемещать с помощью мыши; • DockWidgetFloatable — панель можно вынести в отдельное окно; • DockWidgetVerticalTitleBar — заголовок панели отображается с левой стороны, а не сверху; • NoDockWidgetFeatures — панель нельзя закрыть, переместить и вынести в отдельное окно; features() — возвращает комбинацию установленных свойств панели; toggleViewAction() — возвращает объект действия (экземпляр класса QAction ), с по- мощью которого можно скрыть или отобразить панель. Класс QDockWidget поддерживает следующие полезные сигналы (полный их список можно найти на странице https://doc.qt.io/qt-5/qdockwidget.html): dockLocationChanged(<Область>) — генерируется при переносе панели в другую об- ласть. Внутри обработчика через параметр доступен целочисленный идентификатор области, на которую была перенесена панель; visibilityChanged(<Флаг>) — генерируется при изменении видимости панели. Внутри обработчика через параметр доступно значение True , если панель видима, и False — если скрыта; topLevelChanged(<Флаг>) — генерируется при изменении состояние панели. Внутри об- работчика через параметр доступно значение True , если панель вынесена в отдельное окно, и False — если прикреплена к области. Глава 27. Создание SDI- и MDI-приложений 667 27.5. Управление строкой состояния Класс QStatusBar реализует строку состояния, в которой можно выводить различные сооб- щения. Помимо текстовой информации, туда можно добавить различные компоненты, например индикатор хода выполнения процесса. Строка состояния состоит из трех секций: секция для временных сообщений. Реализована по умолчанию. В эту секцию, в частно- сти, при наведении указателя мыши на пункт меню или кнопку на панели инструментов выводятся сообщения, сохраненные в объекте действия с помощью метода setStatusTip() Вывести пользовательское сообщение во временную секцию можно с помощью метода showMessage() ; обычная секция. При выводе временного сообщения содержимое обычной секции скры- вается. Чтобы отображать сообщения в этой секции, необходимо предварительно доба- вить туда компоненты вызовом метода addWidget() или insertWidget() . Добавленные компоненты выравниваются по левой стороне строки состояния; постоянная секция. При выводе временного сообщения содержимое постоянной секции не скрывается. Чтобы отображать там сообщения, необходимо предварительно добавить туда компоненты методом addPermanentWidget() или insertPermanentWidget() . Добав- ленные компоненты выравниваются по правой стороне строки состояния. Получить ссылку на строку состояния, установленную в главном окне, позволяет метод statusBar() класса QMainWindow , а установить пользовательскую панель вместо стандартной можно с помощью метода setStatusBar( . Иерархия наследования для класса QStatusBar выглядит так: (QObject, QPaintDevice) — QWidget — QStatusBar Формат конструктора класса QStatusBar : <Объект> = QStatusBar([parent=None]) В параметре parent указывается ссылка на родительское окно. Класс QStatusBar наследует все методы базовых классов и поддерживает следующие до- полнительные методы (здесь приведены только основные — полный их список можно най- ти на странице https://doc.qt.io/qt-5/qstatusbar.html): showMessage(<Текст>[, msecs=0]) — выводит временное сообщение. Во втором пара- метре можно указать время в миллисекундах, на которое показывается сообщение: если указано значение 0 , то сообщение показывается, пока не будет выведено новое сообще- ние или вызван метод clearMessage() . Метод является слотом; currentMessage() — возвращает временное сообщение, отображаемое в текущий мо- мент; clearMessage() — удаляет временное сообщение. Метод является слотом; addWidget( — добавляет указанный компонент в конец обыч- ной секции. В параметре stretch может быть указан фактор растяжения; insertWidget(<Индекс>, — добавляет компонент в указанную позицию обычной секции и возвращает индекс позиции. В параметре stretch может быть указан фактор растяжения; addPermanentWidget( — добавляет указанный компонент в ко- нец постоянной секции. В параметре stretch может быть указан фактор растяжения; 668 Часть II. Библиотека PyQt 5 insertPermanentWidget(<Индекс>, — добавляет компонент в ука- занную позицию постоянной секции и возвращает индекс позиции. В параметре stretch может быть указан фактор растяжения; removeWidget( — удаляет компонент из обычной или постоянной секций. При этом сам компонент не удаляется, а только скрывается, лишается родителя и в дальней- шем может быть помещен в другое место; setSizeGripEnabled(<Флаг>) — если в качестве параметра указано значение True , в пра- вом нижнем углу строки состояния будет отображаться маркер изменения размера. Зна- чение False скрывает маркер. Класс QStatusBar поддерживает сигнал messageChanged(<Сообщение>) , генерируемый при изменении текста во временной секции. Внутри обработчика через параметр доступно но- вое сообщение или пустая строка. 27.6. MDI-приложения MDI-приложения (Multiple Document Interface) позволяют, как уже было отмечено ранее, открыть несколько документов одновременно в разных вложенных окнах. Чтобы создать MDI-приложение, следует в качестве центрального компонента установить компонент QMdiArea вызовом метода setCentralWidget() класса QMainWindow . Отдельное окно внутри MDI-области представляется классом QMdiSubWindow 27.6.1. Класс QMdiArea Класс QMdiArea реализует MDI-область, внутри которой могут располагаться вложенные окна (экземпляры класса QMdiSubWindow ). Иерархия наследования для класса QMdiArea вы- глядит так: (QObject, QPaintDevice) — QWidget — QFrame — QAbstractScrollArea — QMdiArea Конструктор класса QMdiArea имеет следующий формат: <Объект> = QMdiArea([parent=None]) В параметре parent указывается ссылка на родительское окно. Класс QMdiArea поддерживает следующие методы (здесь приведены только основные — полный их список можно найти на странице https://doc.qt.io/qt-5/qmdiarea.html): addSubWindow( — создает вложенное окно с флагами flags (см. разд. 18.2), добавляет в него заданный в первом параметре компонент и возвращает ссылку на созданное окно (экземпляр класса QMdiSubWindow ): w = MyWidget() sWindow = self.mdi_area.addSubWindow(w) sWindow.setAttribute(QtCore.Qt.WA_DeleteOnClose) # ... Задаем параметры окна sWindow.show() Чтобы окно автоматически удалялось при закрытии, необходимо установить атрибут WA_DeleteOnClose , а чтобы отобразить окно, — вызвать метод show() В первом параметре этого метода также можно указать ссылку на существующее вло- женное окно (экземпляр класса QMdiSubWindow ): Глава 27. Создание SDI- и MDI-приложений 669 w = MyWidget() sWindow = QtWidgets.QMdiSubWindow() self.mdi_area.addSubWindow(sWindow) sWindow.setAttribute(QtCore.Qt.WA_DeleteOnClose) # ... Производим настройку свойств окна sWindow.setWidget(w) sWindow.show() Также можно добавить вложенное окно в MDI-область, указав последнюю в качестве родителя при создании объекта вложенного окна: sWindow = QtWidgets.QMdiSubWindow(self.mdi_area) activeSubWindow() — возвращает ссылку на активное вложенное окно (экземпляр класса QMdiSubWindow ) или значение None ; currentSubWindow() — возвращает ссылку на текущее вложенное окно (экземпляр класса QMdiSubWindow ) или значение None . Результат выполнения этого метода аналогичен тако- вому у метода activeSubWindow() , если MDI-область находится в активном окне; subWindowList([order=CreationOrder]) — возвращает список со ссылками на все вло- женные окна (экземпляры класса QMdiSubWindow ), добавленные в MDI-область, или пус- той список. В параметре order указываются следующие атрибуты класса QMdiArea : • CreationOrder — 0 — окна в списке располагаются в порядке их создания; • StackingOrder — 1 — окна в списке располагаются в порядке размещения их на экране. Последний элемент в списке будет содержать ссылку на самое верхнее окно, а последний — ссылку на самое нижнее окно; • ActivationHistoryOrder — 2 — окна в списке располагаются в порядке истории по- лучения фокуса. Последний элемент в списке будет содержать ссылку на окно, полу- чившее фокус последним; removeSubWindow( — удаляет вложенное окно из MDI-области; setActiveSubWindow( — делает указанное вложенное окно активным. Если задать значение None , все вложенные окна станут неактивными. Метод является слотом; setActivationOrder(<Порядок>) — задает порядок передачи фокуса при использовании методов activatePreviousSubWindow() , activateNextSubWindow() и др. В параметре ука- зываются те же атрибуты, что и в параметре метода subWindowList() ; activationOrder() — возвращает порядок передачи фокуса; activatePreviousSubWindow() — делает активным предыдущее вложенное окно. Метод является слотом. Порядок передачи фокуса устанавливается с помощью метода setActivationOrder() ; activateNextSubWindow() — делает активным следующее вложенное окно. Метод яв- ляется слотом. Порядок передачи фокуса устанавливается с помощью метода setActivationOrder() ; closeActiveSubWindow() — закрывает активное вложенное окно. Метод является слотом; closeAllSubWindows() — закрывает все вложенные окна. Метод является слотом; cascadeSubWindows() — выстраивает вложенные окна в виде стопки. Метод является слотом; 670 Часть II. Библиотека PyQt 5 tileSubWindows() — выстраивает вложенные окна в виде мозаики. Метод является сло- том; setViewMode(<Режим>) — задает режим отображения вложенных окон в MDI-области. В параметре <Режим> указываются следующие атрибуты класса QMdiArea : • SubWindowView — 0 — в виде собственно окон (по умолчанию); • TabbedView — 1 — в виде отдельных вкладок на панели с вкладками; viewMode() — возвращает режим отображения вложенных окон в MDI-области; setTabPosition(<Позиция>) — задает позицию отображения заголовков вкладок при ис- пользовании режима TabbedView . По умолчанию заголовки вкладок отображаются свер- ху. В качестве параметра <Позиция> могут быть указаны следующие атрибуты класса QTabWidget : • North — 0 — сверху; • South — 1 — снизу; • West — 2 — слева; • East — 3 — справа; tabPosition(<Область>) — возвращает позицию отображения заголовков вкладок при использовании режима TabbedView ; setTabShape(<Форма>) — задает форму углов ярлыков вкладок при использовании режи- ма TabbedView . Могут быть указаны следующие атрибуты класса QTabWidget : • Rounded — 0 — скругленные углы (значение по умолчанию); • Triangular — 1 — треугольная форма; tabShape() — возвращает форму углов ярлыков вкладок в области заголовка при ис- пользовании режима TabbedView ; setTabsMovable(<Флаг>) — если передано значение True , вкладки на панели при исполь- зовании режима TabbedView можно перемещать мышью; setTabsClosable(<Флаг>) — если передано значение True , вкладки на панели при использовании режима TabbedView можно закрывать щелчком на расположенной в за- головке вкладки кнопке закрытия; setBackground( — задает кисть для заполнения фона MDI-области; setOption(<Опция>[, on=True]) — если во втором параметре указано значение True , за- данная в первом параметре опция будет установлена, если False — сброшена. В пара- метре <Опция> может быть указан атрибут DontMaximizeSubWindowOnActivation класса QMdiArea , в случае установки запрещающий автоматически разворачивать следующее вложенное окно при переключении на него из уже развернутого окна; testOption(<Опция>) — возвращает значение True , если указанная опция установлена, и False — в противном случае. Класс QMdiArea поддерживает сигнал subWindowActivated( , генерируемый при активизации другого вложенного окна. В обработчике через параметр доступна ссылка на активизированное вложенное окно или значение None Глава 27. Создание SDI- и MDI-приложений 671 27.6.2. Класс QMdiSubWindow Класс QMdiSubWindow реализует окно, которое может быть отображено внутри MDI-области. Иерархия наследования для него выглядит следующим образом: (QObject, QPaintDevice) — QWidget — QMdiSubWindow Формат конструктора класса QMdiSubWindow : <Объект> = QMdiSubWindow([parent=None][, flags=0]) В параметре parent указывается ссылка на родительское окно. Доступные значения пара- метра flags мы рассматривали в разд. 18.2. Класс QMdiSubWindow наследует все методы базовых классов и дополнительно поддерживает следующие методы (полный их список можно найти на странице https://doc.qt.io/qt-5/ qmdisubwindow.html): setWidget( — помещает компонент в окно; widget() — возвращает ссылку на помещенный в окно компонент; mdiArea() — возвращает ссылку на MDI-область (экземпляр класса QMdiArea ) или значе- ние None ; setSystemMenu( — позволяет установить пользовательское системное меню окна вместо стандартного; systemMenu() — возвращает ссылку на системное меню окна (экземпляр класса QMenu ) или значение None ; showSystemMenu() — открывает системное меню окна. Метод является слотом; setKeyboardSingleStep(<Значение>) — устанавливает шаг изменения размера окна или его положения с помощью клавиш со стрелками. Чтобы изменить размеры окна или его положение с клавиатуры, необходимо в системном меню окна выбрать пункт Перемес- тить или Размер. Значение по умолчанию — 5 ; setKeyboardPageStep(<Значение>) — устанавливает шаг изменения размера окна или его положения с помощью клавиш со стрелками при удержании нажатой клавиши Значение по умолчанию — 20 ; showShaded() — сворачивает содержимое окна, оставляя только заголовок. Метод явля- ется слотом; isShaded() — возвращает значение True , если отображается только заголовок окна, и False — в противном случае; setOption(<Опция>[, on=True]) — если во втором параметре указано значение True , за- данная в первом параметре опция будет установлена, а если False — сброшена. В пара- метре <Опция> могут быть указаны следующие атрибуты класса QMdiSubWindow : • RubberBandResize — если опция установлена, при изменении размеров окна станут изменяться размеры вспомогательного компонента, а не самого окна. По окончании изменения размеров будут изменены размеры окна; • RubberBandMove — если опция установлена, при изменении положения окна станет перемещаться вспомогательный компонент, а не само окно. По окончании переме- щения будет изменено положение окна; testOption(<Опция>) — возвращает значение True , если указанная опция установлена, и False — в противном случае. 672 Часть II. Библиотека PyQt 5 Класс QMdiSubWindow поддерживает следующие сигналы: aboutToActivate() — генерируется перед активацией вложенного окна; windowStateChanged(<Старое состояние>, <Новое состояние>) — генерируется при из- менении состояния окна. Внутри обработчика через параметры доступны целочислен- ные обозначения старого и нового состояний. 27.7. Добавление значка приложения в область уведомлений Класс QSystemTrayIcon позволяет добавить значок приложения в область уведомлений, рас- положенную в правой части панели задач Windows. Иерархия наследования для этого клас- са выглядит так: QObject — QSystemTrayIcon Форматы конструктора класса QSystemTrayIcon : <Объект> = QSystemTrayIcon([parent=None]) <Объект> = QSystemTrayIcon( В параметре parent указывается ссылка на родительское окно. Класс QSystemTrayIcon поддерживает следующие основные методы: isSystemTrayAvailable() — возвращает значение True , если область уведомлений дос- тупна, и False — в противном случае. Метод является статическим; setIcon( — устанавливает значок. Задать значок также можно в конструкторе класса; icon() — возвращает значок (экземпляр класса QIcon ); setContextMenu( — устанавливает контекстное меню, отображаемое при щелч- ке правой кнопкой мыши на значке; contextMenu() — возвращает ссылку на контекстное меню (экземпляр класса QMenu ); setToolTip(<Текст>) — задает текст всплывающей подсказки; toolTip() — возвращает текст всплывающей подсказки; setVisible(<Флаг>) — если в качестве параметра указано значение True , значок будет выведен на экран, а если False — то скрыт. Метод является слотом; show() — отображает значок. Метод является слотом; hide() — скрывает значок. Метод является слотом; isVisible() — возвращает значение True , если значок присутствует на экране, и False — в противном случае; geometry() — возвращает экземпляр класса QRect с размерами и координатами значка на экране; showMessage() — позволяет отобразить сообщение в области уведомлений. Форматы метода: showMessage(<Заголовок>, <Текст сообщения>[, icon=Information][, msecs=10000]) showMessage(<Заголовок>, <Текст сообщения>, Глава 27. Создание SDI- и MDI-приложений 673 В первом формате необязательный параметр icon задает значок, который отображается слева от заголовка сообщения. В качестве значения можно указать атрибуты NoIcon , Information , Warning или Critical класса QSystemTrayIcon Во втором формате, поддерживаемом, начиная с PyQt 5.9, третьим параметром, можно указать произвольный значок. Необязательный параметр msecs задает промежуток времени, в течение которого сооб- щение будет присутствовать на экране. Обратите внимание, что сообщение может не показываться вообще, кроме того, значение параметра msecs в некоторых операционных системах игнорируется. Метод является слотом; supportsMessages() — возвращает значение True , если поддерживается вывод сообще- ний, и False — в противном случае. Метод является статическим. Класс QSystemTrayIcon поддерживает следующие сигналы: activated(<Причина>) — генерируется при щелчке мышью на значке. Внутри обработ- чика через параметр доступна причина в виде целочисленного значения одного из сле- дующих атрибутов класса QSystemTrayIcon : • Unknown — 0 — неизвестная причина; • Context — 1 — нажата правая кнопка мыши; • DoubleClick — 2 — двойной щелчок мышью; • Trigger — 3 — нажата левая кнопка мыши; • MiddleClick — 4 — нажата средняя кнопка мыши; messageClicked() — генерируется при щелчке мышью на сообщении. ГЛ А В А 28 Мультимедиа Библиотека PyQt 5 предоставляет развитые средства воспроизведения звука и видео. Для этого она задействует мультимедийную подсистему Windows Media Foundation, входящую в состав Windows. Следовательно, все форматы, поддерживаемые операционной системой, будут гарантированно поддерживаться и PyQt 5. Воспроизведение звука обеспечивает класс QMediaPlayer , реализующий полноценный муль- тимедийный проигрыватель (но, к сожалению, без какого бы то ни было пользовательского интерфейса). Чтобы воспроизвести видео, в дополнение к классу QMediaPlayer следует ис- пользовать класс QVideoWidget , который реализует панель для вывода собственно видео. Класс QMediaPlaylist обеспечивает функциональность списков воспроизведения (плейли- стов). Класс QAudioRecorder позволяет записывать аудио с микрофона и сохранять в файле. А класс QSoundEffect — наилучший выбор в случае, если необходимо воспроизвести эффект — короткий звуковой фрагмент, например, в качестве оповещения о каком-либо событии. Все описанные в этой главе классы объявлены в модуле QtMultimedia , если не указано иное. 28.1. Класс QMediaPlayer Класс QMediaPlayer реализует полнофункциональный мультимедийный проигрыватель, позволяющий воспроизводить как звук, так и видео из файлов и сетевых источников. Един- ственный его недостаток заключается в том, что он не предоставляет никакого интерфейса для управления воспроизведением: ни кнопок запуска, остановки и паузы, ни регулятора громкости, ни индикатора текущей позиции воспроизведения. Все это нам придется делать самим. Иерархия наследования для класса QMediaPlayer выглядит так: QObject – QMediaObject – QMediaPlayer А формат вызова его конструктора таков: <Объект> = QMediaPlayer([parent=None][, flags=0]) В параметре parent может быть указана ссылка на родительский компонент. Параметр flags позволяет указать дополнительные настройки проигрывателя и должен быть задан в виде одного из значений следующих атрибутов класса QMediaPlayer или их комбинации через оператор | : Глава 28. Мультимедиа 675 LowLatency — 1 — воспроизведение должно начаться с минимальной задержкой. Ис- пользуется при воспроизведении мультимедиа, закодированного в относительно про- стых форматах (например, звук PCM, сохраненный в файле WAV); StreamPlayback — 2 — настраивает проигрыватель для воспроизведения потокового мультимедиа; VideoSurface — 4 — настраивает проигрыватель для использования вместе с обработчи- ками мультимедиа (создание таких обработчиков описано в документации). Класс QMediaPlayer поддерживает следующие наиболее полезные для нас методы (полный их список можно найти на странице https://doc.qt.io/qt-5/qmediaplayer.html): setMedia( — задает источник (мультимедийный файл или сетевой ресурс) для воспроизведения. Источник указывается в виде экземпляра класса QMediaContent . Если передать значение None , заданный ранее источник будет выгружен. Примеры задания источника-файла: mp = QtMultimedia.QMediaPlayer() mc = QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(r"c:\media\song1.mp3")) mp.setMedia(mc) Пример задания сетевого источника: mp.setMedia(QtCore.QUrl(r"http://www.someradio.ru/playlist.m3u8")) Метод является слотом; media() — возвращает заданный источник (экземпляр класса QMediaContent ); setPlaylist( — задает в качестве источника плейлист (экземпляр класса QMediaPlaylist ). Если передать значение None , заданный ранее плейлист будет выгружен. Метод является слотом; playlist() — возвращает заданный плейлист (экземпляр класса QMediaPlaylist ); currentMedia() — возвращает текущий источник мультимедиа. Если был задан один источник вызовом метода setMedia() , возвращаемое значение то же, что и у метода media() . Если был задан плейлист, возвращает позицию плейлиста, воспроизводящуюся в текущий момент. В любом случае возвращаемое значение — экземпляр класса QMediaContent ; play() — начинает или возобновляет воспроизведение мультимедиа. Метод является слотом; stop() — останавливает воспроизведение мультимедиа и перемещает позицию воспро- изведения на начало. Метод является слотом; pause() — приостанавливает воспроизведение мультимедиа. Метод является слотом; state() — возвращает текущее состояние проигрывателя в виде значения одного из сле- дующих атрибутов класса QMediaPlayer : • StoppedState — 0 — воспроизведение либо остановлено, либо еще не начиналось; • PlayingState — 1 — идет воспроизведение; • PausedState — 2 — воспроизведение поставлено на паузу; duration() — возвращает продолжительность воспроизведения мультимедиа в миллисе- кундах; 676 Часть II. Библиотека PyQt 5 position() — возвращает текущую позицию воспроизведения мультимедиа в миллисе- кундах; isSeekable() — возвращает True , если имеется возможность изменить позицию воспро- изведения, и False , если источник этого не поддерживает; setPosition(<Позиция воспроизведения>) — задает текущую позицию воспроизведения в миллисекундах. Метод является слотом; setVolume(<Громкость>) — задает громкость звука в виде числа от 0 (звук отключен) до 100 (максимальная громкость). Метод является слотом; volume() — возвращает громкость звука в виде числа от 0 до 100 ; setMuted(<Флаг>) — если передать значение True , звук будет отключен. Значение False восстанавливает прежнюю громкость. Метод является слотом; isMuted() — возвращает True , если звук в настоящее время отключен, и False — в про- тивном случае; setPlaybackRate(<Скорость воспроизведения>) — задает скорость воспроизведения мультимедиа. Значение параметра должно представлять собой вещественное число, ум- ножаемое на стандартную скорость воспроизведения, чтобы получить ее новую величи- ну. Значение 1.0 задает стандартную скорость, меньшее 1.0 — уменьшенную скорость, а большее 1.0 — увеличенную. Метод является слотом; playbackRate() — возвращает текущую скорость воспроизведения мультимедиа; setVideoOutput( — задает панель для вывода видео, представляемую экземпляром класса QVideoWidget . Используется лишь при воспроизведении видео; mediaStatus() — возвращает состояние источника в виде значения одного из следую- щих атрибутов класса QMediaPlayer : • UnknownMediaStatus — 0 — состояние определить не удается; • NoMedia — 1 — указанный источник отсутствует; • LoadingMedia — 2 — идет загрузка данных источника; • LoadedMedia — 3 — загрузка данных источника закончена; • StalledMedia — 4 — воспроизведение приостановлено из-за опустошения внутренне- го буфера проигрывателя или невозможности загрузить следующую порцию данных; • BufferingMedia — 5 — идет заполнение данными внутреннего буфера проигрывате- ля, однако данных достаточно для продолжения воспроизведения; • BufferedMedia — 6 — внутренний буфер заполнен, идет воспроизведение; • EndOfMedia — 7 — воспроизведение источника закончено; • InvalidMedia — 8 — источник не может быть воспроизведен (неподдерживаемый формат мультимедийных данных, поврежденный файл и т. п.); isAudioAvailable() — возвращает True , если источник содержит звук, и False — в про- тивном случае. Обычно используется при воспроизведении видеороликов, чтобы узнать, имеют ли они звуковое сопровождение; isVideoAvailable() — возвращает True , если источник содержит видео, и False — в противном случае; bufferStatus() — возвращает процент заполнения внутреннего буфера проигрывателя в виде числа от 0 до 100 ; Глава 28. Мультимедиа 677 error() — возвращает ошибку, возникшую при воспроизведении мультимедиа, в виде значения одного из следующих атрибутов класса QMediaPlayer : • NoError — 0 — никакой ошибки не возникло; • ResourceError — 1 — не удалось загрузить источник; • FormatError — 2 — неподдерживаемый формат звука или видео; • NetworkError — 3 — сетевая ошибка; • AccessDeniedError — 4 — недостаточно прав для загрузки источника; • ServiceMissingError — 5 — ошибка в мультимедийной подсистеме; errorString() — возвращает текстовое описание ошибки; isMetaDataAvailable() — возвращает True , если доступны метаданные источника, опи- сывающие хранящиеся в нем мультимедийные данные, и False — в противном случае; metaData(<Ключ>) — возвращает метаданные, относящиеся к заданному в виде строки ключу. Список доступных ключей, которые могут нам пригодиться, приведен далее (полный их список можно найти на странице https://doc.qt.io/qt-5/qmediametadata.html). Если не указано обратное, все значения представляют собой строки, а слово «список» означает обычный список Python (класс list ). • Title — название произведения; • Author — список авторов произведения; • Comment — примечание; • Description — описание; • Genre — список жанров, к которым относится произведение; • Year — год выпуска произведения в виде целого числа; • Date — дата выпуска произведения в виде экземпляра класса datetime.date ; • Language — язык произведения; • Copyright — авторские права создателей произведения; • Size — размер мультимедийного файла в байтах, представленный целым числом; • Duration — продолжительность воспроизведения мультимедийного файла в милли- секундах, заданная целым числом; • AudioBitRate — битрейт звука в виде целого числа, измеряемый в битах в секунду; • AudioCodec — кодек, с помощью которого кодировался звук; • ChannelCount — количество каналов звука в виде целого числа; • AlbumTitle — название альбома, в который входит произведение; • AlbumArtist — автор альбома; • ContributingArtist — список исполнителей, занятых в записи альбома; • Composer — список композиторов, произведения которых входят в альбом; • Conductor — дирижер, занятый в записи альбома; • Lyrics — тексты песен, входящих в альбом; • TrackNumber — порядковый номер произведения в альбоме в виде целого числа; 678 Часть II. Библиотека PyQt 5 • TrackCount — количество произведений в альбоме в виде целого числа; • Resolution — размер видео в виде экземпляра класса QSize ; • VideoFrameRate — частота кадров видео в виде вещественного числа, измеряемая в кадрах в секунду; • VideoBitRate — битрейт видео в виде целого числа, измеряемый в битах в секунду; • VideoCodec — кодек, с помощью которого кодировалось видео; • Director — режиссер фильма; • LeadPerformer — список актеров, занятых в фильме; • Writer — список авторов сценария фильма. Следует отметить, что в источнике совсем не обязательно будут присутствовать все эти данные; availableMetaData() — возвращает список ключей, доступных в источнике метаданных. Класс QMediaPlayer поддерживает большое количество сигналов, из которых для нас пред- ставляют интерес лишь приведенные далее (полный их список можно найти на странице https://doc.qt.io/qt-5/qmediaplayer.html ). mediaChanged( — генерируется при указании другого источника. Но- вый источник передается в параметре; currentMediaChanged( — генерируется при указании другого источни- ка или переходе на новую позицию плейлиста. Новый источник передается в параметре; durationChanged(<Продолжительность>) — генерируется при первом получении или из- менении продолжительности ролика. Новое значение продолжительности, заданное целым числом в миллисекундах, передается обработчику в параметре; stateChanged(<Состояние>) — генерируется при изменении состояния проигрывателя. В параметре обработчику передается новое состояние в виде целочисленного обозна- чения; positionChanged(<Позиция>) — генерируется при изменении позиции воспроизведения. В параметре обработчику передается новая позиция в виде целого числа в миллисе- кундах. По умолчанию такой сигнал генерируется каждые 1000 миллисекунд (1 секунду). Мы можем изменить этот интервал времени, указав нужное значение в вызове метода setNotifyInterval(<Интервал>) класса QMediaPlayer ; volumeChanged(<Громкость>) — генерируется при изменении громкости. В параметре передается новое значение громкости в виде целого числа; mutedChanged(<Флаг>) — генерируется при отключении или, напротив, включении звука. В параметре передается значение True , если звук отключен, или False , если вновь вклю- чен; playbackRateChanged(<Скорость воспроизведения>) — генерируется при изменении ско- рости воспроизведения. В параметре передается новое значение скорости воспроизведе- ния, представленное вещественным числом; mediaStatusChanged(<Состояние источника>) — генерируется при изменении состояния источника. Новое целочисленное обозначение состояния передается в параметре; Глава 28. Мультимедиа 679 bufferStatusChanged(<Состояние буфера>) — генерируется при изменении процента заполнения внутреннего буфера проигрывателя. Новая величина процента заполнения в виде целого числа передается в параметре; error(<Ошибка>) — генерируется при возникновении ошибки. Целочисленное обозначе- ние ошибки передается в параметре; metaDataAvailableChanged(<Флаг>) — генерируется при получении метаданных, запи- санных в ролике. В параметре передается True , если метаданные доступны, или False — в противном случае; metaDataChanged() — генерируется при изменении метаданных ролика; metaDataChanged(<Ключ>, <Значение>) — генерируется при изменении какого-либо зна- чения метаданных ролика. В параметрах передаются строковый ключ изменившегося значения и само это значение. Простейший аудиопроигрыватель (листинг 28.1) предоставляет кнопку для открытия звуко- вого файла, кнопки пуска, паузы и остановки воспроизведения, регулятор текущей позиции воспроизведения, регулятор громкости и кнопку временного отключения звука (рис. 28.1). Рис. 28.1. Интерфейс простейшего аудиопроигрывателя Листинг 28.1. Простейший аудиопроигрыватель from PyQt5 import QtCore, QtWidgets, QtMultimedia import sys class MyWindow(QtWidgets.QWidget): def __init__(self, parent = None): QtWidgets.QWidget.__init__(self, parent, flags=QtCore.Qt.Window | QtCore.Qt.MSWindowsFixedSizeDialogHint) self.setWindowTitle("Аудиопроигрыватель") # Создаем сам проигрыватель self.mplPlayer = QtMultimedia.QMediaPlayer() self.mplPlayer.setVolume(50) self.mplPlayer.mediaStatusChanged.connect(self.initPlayer) self.mplPlayer.stateChanged.connect(self.setPlayerState) vbox = QtWidgets.QVBoxLayout() # Создаем кнопку открытия файла btnOpen = QtWidgets.QPushButton("&Открыть файл...") btnOpen.clicked.connect(self.openFile) vbox.addWidget(btnOpen) 680 Часть II. Библиотека PyQt 5 # Создаем компоненты для управления воспроизведением. # Делаем их изначально недоступными self.sldPosition = QtWidgets.QSlider(QtCore.Qt.Horizontal) self.sldPosition.setMinimum(0) self.sldPosition.valueChanged.connect(self.mplPlayer.setPosition) self.mplPlayer.positionChanged.connect(self.sldPosition.setValue) self.sldPosition.setEnabled(False) vbox.addWidget(self.sldPosition) hbox = QtWidgets.QHBoxLayout() self.btnPlay = QtWidgets.QPushButton("&Пуск") self.btnPlay.clicked.connect(self.mplPlayer.play) self.btnPlay.setEnabled(False) hbox.addWidget(self.btnPlay) self.btnPause = QtWidgets.QPushButton("П&ауза") self.btnPause.clicked.connect(self.mplPlayer.pause) self.btnPause.setEnabled(False) hbox.addWidget(self.btnPause) self.btnStop = QtWidgets.QPushButton("&Стоп") self.btnStop.clicked.connect(self.mplPlayer.stop) self.btnStop.setEnabled(False) hbox.addWidget(self.btnStop) vbox.addLayout(hbox) # Создаем компоненты для управления громкостью hbox = QtWidgets.QHBoxLayout() lblVolume = QtWidgets.QLabel("&Громкость") hbox.addWidget(lblVolume) sldVolume = QtWidgets.QSlider(QtCore.Qt.Horizontal) sldVolume.setRange(0, 100) sldVolume.setTickPosition(QtWidgets.QSlider.TicksAbove) sldVolume.setTickInterval(10) sldVolume.setValue(50) lblVolume.setBuddy(sldVolume) sldVolume.valueChanged.connect(self.mplPlayer.setVolume) hbox.addWidget(sldVolume) btnMute = QtWidgets.QPushButton("&Тихо!") btnMute.setCheckable(True) btnMute.toggled.connect(self.mplPlayer.setMuted) hbox.addWidget(btnMute) vbox.addLayout(hbox) self.setLayout(vbox) self.resize(300, 100) # Для открытия файла используем метод getOpenFileUrl() класса # QFileDialog, т. к. для создания экземпляра класса # QMediaContent нам нужен путь к файлу, заданный в виде # экземпляра класса QUrl def openFile(self): file = QtWidgets.QFileDialog.getOpenFileUrl(parent=self, caption = "Выберите звуковой файл", filter = "Звуковые файлы (*.mp3 *.ac3)") self.mplPlayer.setMedia(QtMultimedia.QMediaContent(file[0])) Глава 28. Мультимедиа 681 def initPlayer(self, state): if state == QtMultimedia.QMediaPlayer.LoadedMedia: # После загрузки файла подготавливаем проигрыватель # для его воспроизведения self.mplPlayer.stop() self.btnPlay.setEnabled(True) self.btnPause.setEnabled(False) self.sldPosition.setEnabled(True) self.sldPosition.setMaximum(self.mplPlayer.duration()) elif state == QtMultimedia.QMediaPlayer.EndOfMedia: # По окончании воспроизведения файла возвращаем # проигрыватель в изначальное состояние self.mplPlayer.stop() self.sldPosition.setValue(0) self.sldPosition.setEnabled(False) self.btnPlay.setEnabled(False) self.btnPause.setEnabled(False) self.btnStop.setEnabled(False) elif state == QtMultimedia.QMediaPlayer.NoMedia or state == QtMultimedia.QMediaPlayer.InvalidMedia: # Если файл не был загружен, отключаем компоненты, # управляющие воспроизведением self.sldPosition.setValue(0) self.sldPosition.setEnabled(False) self.btnPlay.setEnabled(False) self.btnPause.setEnabled(False) self.btnStop.setEnabled(False) # В зависимости от того, воспроизводится ли файл, поставлен # ли он на паузу или остановлен, делаем соответствующие кнопки # доступными или недоступными def setPlayerState(self, state): if state == QtMultimedia.QMediaPlayer.StoppedState: self.sldPosition.setValue(0) self.btnPlay.setEnabled(True) self.btnPause.setEnabled(False) self.btnStop.setEnabled(False) elif state == QtMultimedia.QMediaPlayer.PlayingState: self.btnPlay.setEnabled(False) self.btnPause.setEnabled(True) self.btnStop.setEnabled(True) elif state == QtMultimedia.QMediaPlayer.PausedState: self.btnPlay.setEnabled(True) self.btnPause.setEnabled(False) self.btnStop.setEnabled(True) app = QtWidgets.QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_()) 682 Часть II. Библиотека PyQt 5 В листинге 28.2 приведен код служебной утилиты, выводящей метаданные, которые хра- нятся в загруженном мультимедийном файле. В настоящий момент она выводит сведения об открытом в ней аудиофайле (рис. 28.2). Рис. 28.2. Интерфейс утилиты, выводящей метаданные мультимедийного файла Листинг 28.2. Вывод метаданных мультимедийного файла from PyQt5 import QtCore, QtWidgets, QtMultimedia import sys class MyWindow(QtWidgets.QWidget): def __init__(self, parent = None): QtWidgets.QWidget.__init__(self, parent, flags=QtCore.Qt.Window | QtCore.Qt.MSWindowsFixedSizeDialogHint) self.setWindowTitle("Метаданные") self.mplPlayer = QtMultimedia.QMediaPlayer() self.mplPlayer.setVolume(50) self.mplPlayer.mediaStatusChanged.connect(self.showMetadata) vbox = QtWidgets.QVBoxLayout() btnOpen = QtWidgets.QPushButton("&Открыть файл...") btnOpen.clicked.connect(self.openFile) vbox.addWidget(btnOpen) # Создаем доступное только для чтения многострочное текстовое # поле, в которое будет выводиться результат self.txtOutput = QtWidgets.QTextEdit() self.txtOutput.setReadOnly(True) vbox.addWidget(self.txtOutput) self.setLayout(vbox) self.resize(300, 250) def openFile(self): file = QtWidgets.QFileDialog.getOpenFileUrl(parent=self, caption = "Выберите звуковой файл", Глава 28. Мультимедиа 683 filter = "Звуковые файлы (*.mp3 *.ac3)") self.mplPlayer.setMedia(QtMultimedia.QMediaContent(file[0])) def showMetadata(self, state): self.txtOutput.clear() # Как только файл будет загружен... if state == QtMultimedia.QMediaPlayer.LoadedMedia: # ...извлекаем ключи всех доступных метаданных... keys = self.mplPlayer.availableMetaData() s = "" # ...перебираем их в цикле... for k in keys: v = self.mplPlayer.metaData(k) # ...на случай пустых списков проверяем, действительно # ли по этому ключу хранится какое-то значение... if v: # ...если значение представляет собой список, # преобразуем его в строку... if v is list: v = ", ".join(v) # ...формируем на основе значений текст... s += " |