Шаг 11.
Библиотека PyQt5.
Знакомство с PyQt5. Управление основным циклом приложения

    На этом шаге мы рассмотрим особенности управления этим циклом.

    Для взаимодействия с системой и обработки возникающих сигналов предназначен основной цикл приложения. После вызова метода ехес_() программа переходит в бесконечный цикл. Инструкции, расположенные после вызова этого метода, будут выполнены только после завершения работы всего приложения. Цикл автоматически прерывается после закрытия последнего открытого окна приложения. С помощью статического метода setQuitOnLastWindowClosed() из класса QApplication это поведение можно изменить.

    Чтобы завершить работу приложения, необходимо вызвать слот quit() или метод exit([returnCode=0]) класса QApplication. Поскольку программа находится внутри цикла, то вызвать эти методы можно лишь при наступлении какого-либо события, - например, при нажатии пользователем кнопки.

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

    Если внутри обработчика выполняется длительная операция, то программа перестает реагировать на события. В качестве примера изобразим длительный процесс с помощью функции sleep() из модуля time.

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets

import sys, time
def on_clicked():
    time.sleep(10) # "Засыпаем" на 10 секунд

app = QtWidgets.QApplication(sys.argv)
button = QtWidgets.QPushButton("Запустить процесс")
button.resize(200, 40)
button.clicked.connect(on_clicked)
button.show()
sys.exit(app.exec_())
Архив с файлом можно взять здесь.

    В этом примере при нажатии кнопки Запустить процесс вызывается функция on_clicked(), внутри которой мы приостанавливаем выполнение программы на десять секунд и тем самым прерываем основной цикл. Попробуйте нажать кнопку, перекрыть окно другим окном, а затем заново его отобразить, - вам не удастся это сделать, поскольку окно перестает реагировать на любые события, пока не закончится выполнение процесса. Короче говоря, программа просто зависнет.

    Длительную операцию можно разбить на несколько этапов и по завершении каждого этапа выходить в основной цикл с помощью статического метода processEvents([flags=AllEvents]) из класса QCoreApplication, от которого наследуется класс QApplication. Переделаем предыдущую программу, инсценировав с помощью цикла длительную операцию, которая выполняется 20 секунд.

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets

import sys, time
def on_clicked():
    button.setDisabled(True)	# Делаем кнопку неактивной
    for i in range(1, 21):
        QtWidgets.qApp.processEvents()  # Запускаем оборот цикла
        time.sleep(1)	# "Засыпаем" на 1 секунду
        print("step -", i)
        button.setDisabled(False)       # Делаем кнопку активной

app = QtWidgets.QApplication(sys.argv)
button = QtWidgets.QPushButton("Запустить процесс")
button.resize(200, 40)
button.clicked.connect(on_clicked)
button.show()
sys.exit(app.exec_())
Архив с файлом можно взять здесь.

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

    Со следующего шага мы начнем рассматривать многопоточные приложения.




Предыдущий шаг Содержание Следующий шаг