На этом шаге мы рассмотрим пример повторного использования кода.
Создание объекта приложения и экземпляра класса MyWindow производится внутри условия:
if __name__ == "__main__" :
Атрибут модуля __name__ будет содержать значение __main__ только в случае запуска модуля как главной программы. Если модуль импортировать, то атрибут будет содержать другое значение. Поэтому весь последующий код создания объекта приложения и объекта окна выполняется только при запуске программы двойным щелчком на значке файла. Может возникнуть вопрос, зачем это нужно? Дело в том, что одним из преимуществ ООП-стиля программирования является повторное использование кода. Следовательно, можно импортировать модуль и использовать класс MyWindow в другом приложении.
Рассмотрим эту возможность на примере, для чего сохраним код из предыдущего шага в файле с именем MyWindow.py, а затем создадим в той же папке еще один файл (например, с именем test.pyw) и вставим в него следующий код:
# -*- coding: utf-8 -*- from PyQt5 import QtCore, QtWidgets import MyWindow class MyDialog(QtWidgets.QDialog): def __init__(self, parent=None): QtWidgets.QDialog.__init__(self, parent) self.myWidget = MyWindow.MyWindow() self.myWidget.vbox.setContentsMargins(0, 0, 0, 0) self.button = QtWidgets.QPushButton("&Изменить надпись") mainBox = QtWidgets.QVBoxLayout() mainBox.addWidget(self.myWidget) mainBox.addWidget(self.button) self.setLayout(mainBox) self.button.clicked.connect(self.on_clicked) def on_clicked(self): self.myWidget.label.setText("Новая надпись") self.button.setDisabled(True) if __name__ == "__main__" : import sys app = QtWidgets.QApplication(sys.argv) window = MyDialog() window.setWindowTitle("Преимущество ООП-стиля") window.resize(300, 100) window.show() sys.exit(app.exec_())
Теперь запустим файл test.pyw двойным щелчком - на экране откроется окно с надписью и двумя кнопками (рисунок 1).
Рис.1. Результат выполнения приложения
По нажатию на кнопку Изменить надпись производится изменение текста надписи, и кнопка делается неактивной. Нажатие кнопки Закрыть окно будет по-прежнему завершать выполнение приложения.
В этом примере мы создали класс MyDialog, который наследует класс QDialog. Поэтому при выводе окно автоматически выравнивается по центру экрана. Кроме того, в заголовке окна выводятся только две кнопки: Справка и Закрыть. Внутри конструктора мы создаем экземпляр класса MyWindow и сохраняем его в атрибуте myWidget:
self.myWidget = MyWindow.MyWindow()
С помощью этого атрибута можно получить доступ ко всем атрибутам класса MyWindow. Например, в следующей строке производится изменение отступа между границами контейнера и границами соседних элементов:
self.myWidget.vbox.setContentsMargins(0, 0, 0, 0)
В следующих инструкциях внутри конструктора производится создание объекта кнопки и контейнера, затем экземпляр класса MyWindow и объект кнопки добавляются в контейнер, а сам контейнер помещается в основное окно.
Выражение:
self.button.clicked.connect(self.on_clicked)
Вот так и производится повторное использование ранее написанного кода: мы создаем класс и сохраняем его внутри отдельного модуля, а чтобы протестировать модуль или использовать его как отдельное приложение, размещаем код создания объекта приложения и объекта окна внутри условия:
if __name__ == "__main__" :
Тогда при запуске с помощью двойного щелчка на значке файла производится выполнение кода как отдельного приложения. Если модуль импортируется, то создание объекта приложения не производится, и мы можем использовать класс в других приложениях. Например так, как это было сделано в примере этого шага, или путем наследования класса и добавления или переопределения методов.
В некоторых случаях использование ООП-стиля является обязательным. Например, чтобы обработать нажатие клавиши на клавиатуре, необходимо наследовать какой-либо класс и переопределить в нем метод с предопределенным названием. Какие методы необходимо переопределять, мы рассмотрим при изучении обработки событий.
На следующем шаге мы рассмотрим создание окна с помощью программы Qt Designer.