При разрабтке GUI приложения, независимо от языка программирования и фреймворка, возникает необходимость "навести марафет". Для этого добавляются приятные глазу элементы интерфейса. Один из таких элементов - иконка приложения.
Возможна такая ситуация, когда иконку необходимо загрузить по сети, и в PyQt5 есть встроенные методы для решения этой задачи. В данной заметке мы рассмотрим использование QNetworkAccessManager
и QNetworkRequest
.
Импортируем необходимые классы и приступаем:
- Создаем главное окно, остальное сделаем в инициализаторе.
- Создаем экземпляр класса
QNetworkAccessManager
:self.nam = QNetworkAccessManager(self)
, он будет заниматься обработкой запроса в асинхронном виде - интерфейс программы не будет зависать во время загрузки, так как она не будет блокировать поток. - Создаем метод, который будет принимать объект класса
QNetworkReply
и устанавливать загруженную картинку как иконку:
# принимаем self, так как это метод класса и reply - объект, который передается по сигналу
def set_window_icon_from_reply(self, reply):
# Создаем объект класса QPixmap
pixmap = QPixmap()
# у QPixmap есть метод загрузки байтов. это то, что нам нужно:
# считываем байты ответа и передаём их методу loadFromData
pixmap.loadFromData(reply.readAll())
# Делаем объект класса QIcon на основе готового объекта pixmap
icon = QIcon(pixmap)
# Устанавливаем иконку окна:
self.setWindowIcon(icon)
- Подключаем к сигналу о результате загрузки принимающий слот:
self.nam.finished.connect(self.set_window_icon_from_reply)
- Создаём и запускаем запрос:
self.nam.get(QNetworkRequest(QUrl(ICON_IMAGE_URL)))
Тут мы преобразуем строкуICON_IMAGE_URL
в объект классаQUrl
, создаем запросQNetworkRequest
и передаем методуget
у объектаself.nam
.
Запускаем приложение, во время инициализации создается запрос и выполняется асинхронно. После выполнения запроса устанавливается иконка окна.
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout
ICON_IMAGE_URL = "https://cdn.icon-icons.com/icons2/478/PNG/512/slack_47017.png"
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.label = QLabel('Image loading demo')
self.vertical_layout = QVBoxLayout()
self.vertical_layout.addWidget(self.label)
self.setLayout(self.vertical_layout)
self.nam = QNetworkAccessManager(self)
self.nam.finished.connect(self.set_window_icon_from_reply)
self.nam.get(QNetworkRequest(QUrl(ICON_IMAGE_URL)))
self.resize(255, 42)
def set_window_icon_from_reply(self, reply):
pixmap = QPixmap()
pixmap.loadFromData(reply.readAll())
icon = QIcon(pixmap)
self.setWindowIcon(icon)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())