Быстрый в изучении - мощный в программировании
Скрипт ИНВЕСТОР на Python

Попробуйте себя в качестве инвестора имея в помощники мощный алгоритм советника на Python...

Все уроки по PyQt5

PyQt5 реализован как комплект Python-модулей. Он включает в себя около 620 классов и 6000 функций и методов...

Скрипт отправки SMS через Python

Была задача отправить SMS-ки большому списку номеров телефона с уточнением цены за всю рассылку "До" ее отправки...

Первые программы на PyQt5 [Урок 2]

programmy-na-pyqt5.png

В этой части руководства PyQt5

мы изучим некоторую базовую функциональность.

Этот простой пример выводит маленькое окно. Мы можем делать множество вещей с этим окном. Мы можем менять его размер, раскрывать на весь экран или свернуть в панель задач. Это потребовало бы много программного кода. Кто-то уже запрограммировал эту функциональность. Поскольку это повторяется в большинстве приложений, нет необходимости программировать это с самого начала. PyQt5 – это инструментарий высокого уровня. Если бы мы писали с помощью инструментов более низкого уровня, нижеследующий пример кода мог бы с лёгкостью содержать сотни строк.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QApplication, QWidget
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = QWidget()
    w.resize(250, 150)
    w.move(300, 300)
    w.setWindowTitle('Simple')
    w.show()
    
    sys.exit(app.exec_())

Пример кода выше выводит маленькое окно на экране.

import sys
from PyQt5.QtWidgets import QApplication, QWidget

Здесь мы обеспечили необходимый импорт модулей. Основные виджеты расположены в модуле PyQt5.QtWidgets.

app = QApplication(sys.argv)

Каждое приложение PyQt5 должно создать объект приложения. Параметр sys.argv - это список аргументов из командной строки. Скрипты Python могут быть запущены из программной оболочки. Это один из способов, как мы можем контролировать запуск наших скриптов.

w = QWidget()

Виджет QWidget – это основной класс всех объектов пользовательского интерфейса в PyQt5. Мы обеспечиваем конструктор по умолчанию для QWidget. Конструктор по умолчанию не имеет родителя. Виджет без родителя называется окном.

w.resize(250, 150)

Метод resize() изменяет размер виджета. Здесь задана ширина 250px и высота 150px.

w.move(300, 300)

Метод move() перемещает виджет на позицию с координатами x=300 и y=300 на экране.

w.setWindowTitle('Simple')

Здесь мы устанавливаем название нашего окна. Оно показывается в строке заголовка.

w.show()

Метод show() отображает виджет на экране. Виджет сначала создаётся в памяти и позже показывается на экране.

sys.exit(app.exec_())

Наконец, мы входим в главный цикл приложения. Обработка событий начинается в этой точке. Главный цикл получает события из системы и отправляет их виджетам приложения. Цикл завершается, если мы вызываем метод exit() или главное окно было закрыто. Метод sys.exit() гарантирует чистый выход. Среда будет проинформирована, когда приложение завершится.

Метод exec_() содержит нижнее подчеркивание, потому что exec – уже используемое имя в Python. И, соответственно, имя exec_() было использовано взамен.

Окно Simple

Рисунок: Окно Simple

Иконка приложения

Иконка приложения – это маленькое изображение, которое обычно отображается в верхнем левом углу строки заголовка. В следующем примере мы увидим, как сделать её в PyQt5. Мы также познакомимся с несколькими новыми методами.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
 
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):
        self.setGeometry(300, 300, 300, 220)
        self.setWindowTitle('Icon')
        self.setWindowIcon(QIcon('web.png'))        
    
        self.show()
        
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())  

Предыдущий пример был написан в процедурном стиле. Язык программирования Python поддерживает и процедурный, и объектно-ориентированный стиль программирования. Программирование в PyQt5 означает объектно-ориентированное программирование (ООП).

class Example(QWidget):
    def __init__(self):
        super().__init__()
        ...

Есть три важных вещи в объектно-ориентированном программировании – это классы, данные и методы. Здесь мы создаём новый класс с именем Example. Класс Example наследуется из класса QWidget. Это значит, что мы вызываем два конструктора: первый для класса Example и второй для унаследованного класса. Метод super() возвращает объект родителя класса Example и мы вызываем его конструктор. Метод __init__() – это конструктор класса в языке Python.

self.initUI()

Создание GUI поручено методу initUI().

self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))

Все три метода были унаследованы из класса QWidget. setGeometry делает две вещи: он определяет место окна на экране и устанавливает его размер. Первые два параметра – позиции x и y нашего окна. Третий – ширина, и четвёртый – высота окна. Фактически, setGeometry сочетает методы resize() и move() в одном. Последний метод устанавливает иконку приложения. Чтобы сделать это, мы создали объект QIcon. QIcon принимает путь к нашей иконке для её отображения.

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

Приложение и объекты примера созданы. Главный цикл запущен.

Окно с иконкой

Рисунок: Окно с иконкой

Показ всплывающих подсказок

Мы можем обеспечить любой из наших виджетов всплывающей подсказкой.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import (QWidget, QToolTip, QPushButton, QApplication)
from PyQt5.QtGui import QFont    
class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
        
    def initUI(self):
        QToolTip.setFont(QFont('SansSerif', 10))
        
        self.setToolTip('This is a <b>QWidget</b> widget')
        
        btn = QPushButton('Button', self)
        btn.setToolTip('This is a <b>QPushButton</b> widget')
        btn.resize(btn.sizeHint())
        btn.move(50, 50)       
        
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Tooltips')    
        self.show()
        
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

В этом примере, мы показываем подсказку для двух PyQt5 виджетов.

QToolTip.setFont(QFont('SansSerif', 10))

Этот статический метод устанавливает шрифт, используемый для показа всплывающих подсказок. Мы используем шрифт 10px SansSerif.

self.setToolTip('This is a <b>QWidget</b> widget')

Чтобы создать подсказку, мы вызываем метод setTooltip(). Мы можем использовать HTML форматирование текста.

btn = QPushButton('Button', self)
btn.setToolTip('This is a <b>QPushButton</b> widget')

Мы создаём виджет кнопки и устанавливаем всплывающую подсказку для неё.

btn.resize(btn.sizeHint())
btn.move(50, 50)

Меняем размер у кнопки, перемещаем её в окно. Метод sizeHint() даёт рекомендуемый размер для кнопки.

Всплывающие подсказки

Рисунок: Всплывающие подсказки

Закрытие окна

Очевидный способ закрыть окно – это кликнуть на знаке «X» в строке заголовка. В следующем примере, мы покажем, как мы можем программно закрыть наше окно. Мы кратко коснёмся темы сигналов и слотов.

Ниже следует конструктор виджета QPushButton, который мы используем в нашем примере.

QPushButton(string_text, QWidget parent = None)

Параметр string_text – это текст, который будет отображён на кнопке. Parent – это виджет, на котором мы разместим нашу кнопку. В этом случае это будет QWidget.

Виджеты имеют иерархическую форму. В этой иерархии большинство виджетов имеют родителей. Виджеты без родителей – это окна верхнего уровня.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
from PyQt5.QtCore import QCoreApplication
 
class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):               
        qbtn = QPushButton('Quit', self)
        qbtn.clicked.connect(QCoreApplication.instance().quit)
        qbtn.resize(qbtn.sizeHint())
        qbtn.move(50, 50)       
        
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Quit button')    
        self.show()
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

В этом примере, мы создали кнопку выхода. После нажатия на кнопку, приложение завершается.

from PyQt5.QtCore import QCoreApplication

Нам необходим объект из модуля QtCore.

qbtn = QPushButton('Quit', self)

Мы создали кнопку. Кнопка является образцом класса QPushButton. Первый параметр конструктора – это метка кнопки. Второй параметр – родительский виджет. Виджет родителя – это Example, который наследуется из QWidget.

qbtn.clicked.connect(QCoreApplication.instance().quit)

Система обработки событий в PyQt5 построена на механизме сигналов и слотов. Если мы кликаем по кнопке, выдаётся сигнал clicked. Слот может быть слотом Qt или любым слотом, вызываемым из Python. QCoreApplication содержит цикл главного события; он обрабатывает и выполняет все события. Метод instance даёт нам его текущий экземпляр. Заметим, что QCoreApplication создаётся с QApplication. Кликнутый сигнал соединяется с методом quit(), который и завершает приложение. Взаимосвязь сделана между двумя объектами: отправителем и получателем. Отправитель – нажатие кнопки, получатель – объект приложения.

Кнопка выхода

Рисунок: Кнопка выхода

Диалоговое окно

По умолчанию, если вы кликаете по кнопке «X» в строке заголовка, QWidget закрывается. Иногда мы хотим изменить это стандартное поведение. К примеру, если у нас есть открытый в редакторе файл, в котором мы сделали некоторые изменения, мы показываем сообщение для подтверждения выхода.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QWidget, QMessageBox, QApplication
 
class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):               
        self.setGeometry(300, 300, 250, 150)        
        self.setWindowTitle('Message box')    
        self.show()
        
    def closeEvent(self, event):
        reply = QMessageBox.question(self, 'Message', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()        
        
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

Если мы закрываем QWidget, вызывается QCloseEvent. Чтобы изменить поведение виджета, нам необходимо переопределить обработчик событий closeEvent().

reply = QMessageBox.question(self, 'Message', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

Мы показываем сообщение с двумя кнопками: «Yes» и «No». Первая строка появляется в строке заголовка. Вторая строка – это текст сообщения, отображаемый с помощью диалогового окна. Третий аргумент указывает комбинацию кнопок, появляющихся в диалоге. Последний параметр – кнопка по умолчанию. Это кнопка, которая первоначально имеет на себе указатель клавиатуры. Возвращаемое значение хранится в переменной reply.

if reply == QtGui.QMessageBox.Yes:
    event.accept()
else:
    event.ignore()

Здесь мы проверяем возвращаемое значение. Если мы кликаем кнопку «Yes», мы принимаем событие, которое ведёт к закрытию виджета и завершению приложения. В противном случае, мы игнорируем закрывающее событие.

Диалоговое окно

Рисунок: Диалоговое окно

Центрирование окна на экране

Нижеследующий скрипт показывает, как мы можем центрировать окно экране.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication
 
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):               
        self.resize(250, 150)
        self.center()
        self.setWindowTitle('Center')    
        self.show()
        
    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

Класс QtGui.QDesktopWidget предоставляет информацию о пользовательском рабочем столе, включая размер экрана.

self.center()

Код, который будет центрировать окно, размещён в специальном методе center().

qr = self.frameGeometry()

Мы получаем прямоугольник, точно определяющий форму главного окна.

cp = QDesktopWidget().availableGeometry().center()

Мы выясняем разрешение экрана нашего монитора. Из этого разрешения, мы получаем центральную точку.

qr.moveCenter(cp)

Наш прямоугольник уже имеет высоту и ширину. Теперь мы устанавливаем центр прямоугольника в центр экрана. Размер прямоугольника не изменяется.

self.move(qr.topLeft())

Мы перемещаем верхнюю левую точку окна приложения в верхнюю левую точку прямоугольника qr, таким образом центрируя окно на нашем экране.

В этой части руководства PyQt5, мы успели изучить некоторые основы...

Продолжение: Меню и панели инструментов в PyQt5 [Урок №3]

Прошлый урок: Введение в PyQt5 [Урок 1]

twitter.com facebook.com vkontakte.ru odnoklassniki.ru mail.ru ya.ru yandex.ru
Комментариев: 4
  1. Коллеги!

    В примере по изменению иконки окна (приложения) ни чего не происходит.

    Я так понимаю у вас в примере использовались встроенные значки? или файл

    из текущего каталога? в любом случае метод QIcon создает объект даже при

    не правильном имени, и значек окна приложения не меняется.

    Как понять в чем дело? Буду рад подсказке.

  2. Привет Игорь.

    Следующая строка:

    self.setWindowIcon(QIcon('web.png'))

    отвечает за внедрение иконки. Картинка web.png должна находиться в той же папке где находится исполняемый Python скрипт.

    У вас Linux или Windows? У мена на Ubuntu работает, только что проверил.

  3. Archy, спасибо что откликнулся!

    У меня Ubunu 16.04, самое смешное, что проверил в Windows все работает, на Linux нет. Причем проблема не в QIcon, как я думал в начале, а в setWindowIcon. Icon на кнопку (Button) вывести смог. а вот на окне - засада. И не работает пример с меню (MenuBar), при чем проверил в Windows все работает.

  4. QIcon в Ubuntu16.04 как и у предыдущего автора не внедряет иконку. Как исправить? Просто и в следующем уроке QIcon не вставляет картинку (для кнопки выхода в панели инструментов)

Оставьте комментарий!

Используйте нормальные имена.

Имя и сайт используются только при регистрации

Если вы уже зарегистрированы как комментатор или хотите зарегистрироваться, укажите пароль и свой действующий email. При регистрации на указанный адрес придет письмо с кодом активации и ссылкой на ваш персональный аккаунт, где вы сможете изменить свои данные, включая адрес сайта, ник, описание, контакты и т.д., а также подписку на новые комментарии.

(обязательно)