Доброе утро али день, мой дорогой друг!
Через несколько дней наступит долгожданная и ненавистная пора школьных занятий и миллионы юных и сонных неучей устремятся в школы за знаниями.
Там их будут мучить домашними заданиями, тестами и прочими контрольными.
А самые юные из них начнут свое знакомство с НЕЙ - великой и ужасной - Таблицей Умножения!
Конечно, родители дома будут продолжать мучить несчастных, неожиданно задавая вопрос посреди разговора: "семь умножить на восемь, быстро??", от чего становится еще тоскливее и печальнее...
Вот было бы классно, если можно выучить таблицу умножения с другом. Причем, с таким другом, который, конечно, круче самих родителей... Например, с Бэтменом!
А у меня и телефончик его завалялся=)
Эй, Рыцарь Ночи, помоги выучить таблицу умножения, будь другом!
Цель
Через несколько дней наступит долгожданная и ненавистная пора школьных занятий и миллионы юных и сонных неучей устремятся в школы за знаниями.
Там их будут мучить домашними заданиями, тестами и прочими контрольными.
А самые юные из них начнут свое знакомство с НЕЙ - великой и ужасной - Таблицей Умножения!
Конечно, родители дома будут продолжать мучить несчастных, неожиданно задавая вопрос посреди разговора: "семь умножить на восемь, быстро??", от чего становится еще тоскливее и печальнее...
Вот было бы классно, если можно выучить таблицу умножения с другом. Причем, с таким другом, который, конечно, круче самих родителей... Например, с Бэтменом!
А у меня и телефончик его завалялся=)
Эй, Рыцарь Ночи, помоги выучить таблицу умножения, будь другом!
Цель
Итак, сегодня мы с помощью программирования совершим маленькое чудо, и напишем программу для изучения таблицы умножения для юных страдальцев.
Программа должна иметь графический интерфейс, иметь визуальную стилистику Темного Рыцаря, говорить голосом Бэтмена. Казалось бы, такая классная программа нужна и важна сама по себе, но нет, возьмем планку выше - она еще должна случайным образом задавать вопросы, типа "2x2=?" и проверять ответы.
Начнем с главного вопроса: чем будем рисовать окошки?
Конечно моей первой мыслью, как программиста на Java, было Swing, но...
От мысли, что нужно писать детскую веселую программку на могучем и грозном языке Enterprise разработки, повеяло холодком и я отложил эту мысль подальше.
Что же еще умеет рисовать красивые окошки?
Причем хотелось бы именно рисовать, не утруждая себя написанием кода, который задает местоположение кнопочек в окне.
И тут я вспомнил про Qt. Великий и прекрасный Qt!
С помощью Qt можно нарисовать любые, самые фантастические окошки. Существует QtCreator и QtDesigner для таких лентяев как я, которые хотят просто набросать кнопочек на поле - и все готово.
Но есть один ужасный минус - чтобы использовать Qt, нужно писать на C++.
А от мысли, что нужно писать детскую веселую программку на C++, повеяло таким морозом, что я, как Эддард Старк, забормотал: "Зима близко..."
И все-таки Qt мне нравится, можно ли как-то обойтись без C++?
Оказалось, можно!
Qt for Python
А не написать ли мне все на Python? А что, мне это нравится))
Сочетание простого лаконичного синтаксиса Python и мощь графической библиотеки Qt - это однозначно круто!
Разработчики Qt, видимо, тоже так думали, когда создавали Qt for Python, официальную библиотеку на Python для работы с Qt.
Спасибо им за это огромное от лица всех школьников, еще не выучивших таблицу умножения!
Инструменты
Итак, для создания нашей чудо-программы, мы будем использовать:
- Python v3.7.3;
- Jetbrans PyCharm в качестве IDE;
- QtDesigner v5.11.1 в качестве рисовалки окошек;
- Горячий шоколад, для придания себе отличного настроения!
Теперь, когда мы во всеоружии - поехали!
Рисуем окошко
Итак, скачиваем QtDesigner, запускаем его. Он сразу предлагает создать форму, выбираем вариант Main Window.
Форма нашей программы очень простая и содержит всего 4 элемента:
- Картинка с Бэтменом (QLabel);
- Надпись с вопросом, типа 2x2 (QLabel);
- Поле вводе ответа (QTextEdit);
- Кнопка проверки ответа (QPushButton).
Все эти элементы управления нашел в списке виджетов, перетащил мышкой на формочку и подогнал по размеру.
Единственный неожиданный для меня момент оказался связан с тем, что картинка на формочке - это тоже QLabel, ну то есть надпись.
Но не будем формалистами, работает и ладно.
Получилось что-то такое:
Нажатием клавиш Ctrl+R можно запустить окошко и посмотреть его в режиме предпросмотра. Удобно.
С рисованием закончено, сохраняем форму в виде файла main.ui вместе с картинкой Бэтмена и иконкой стрелки повтора для кнопки в одну папку.
Не спорьте с PyCharm и соглашайтесь, она знает, что делает=)
Теперь, когда все нужные библиотеки установлены, нужно загрузить формочку, нарисованную в QtCreator.
Это делается всего одной строчкой:
Создадим собственный класс BatTestForm, который будет наследоваться от класса Form и содержать логику игры
И вот так эта красота выглядит в работающем виде:battest
├── batman.png
├── refresh.png
└── main.ui
Содержимое файла main.ui выглядит примерно так:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>722</width>
<height>405</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="batman">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>371</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>back.png</pixmap>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>440</x>
<y>10</y>
<width>271</width>
<height>51</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>30</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QTextEdit" name="result">
<property name="geometry">
<rect>
<x>440</x>
<y>90</y>
<width>271</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>30</pointsize>
</font>
</property>
<property name="acceptRichText">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="refresh">
<property name="geometry">
<rect>
<x>444</x>
<y>172</y>
<width>271</width>
<height>181</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>refresh.png</normaloff>refresh.png</iconset>
</property>
<property name="iconSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>722</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
Теперь нужно написать немного кода на Python, чтобы придать этой красоте немного жизни))
Пишем код
Создаем в нашей папочке battest файл main.py, который будет содержать весь код нашей программы.
Для начала, нам нужно импортировать все необходимые библиотеки:
#Доступ к функциям операционной системы
import sys
#Генератор случайных чисел
import random
#Для работы с аудио
from playsound import playsound
#Загрузчик формочек от QtCreator
from PyQt5 import uic
#Классики для работы с Qt
from PyQt5.QtWidgets import QApplication, QMessageBox, QErrorMessage
Это все библиотеки, которые нам понадобятся. Если каких-то библиотек не окажется на вашем компьютере, то PyCharm любезно спросит нас, не хотим ли мы их установить.Не спорьте с PyCharm и соглашайтесь, она знает, что делает=)
Теперь, когда все нужные библиотеки установлены, нужно загрузить формочку, нарисованную в QtCreator.
Это делается всего одной строчкой:
#Загружаем формочку, нарисованную в QtCreator
Form, Window = uic.loadUiType("main.ui")
В результате загрузки формы у нас есть два класса Form и Window, которые мы используем для отображения нарисованной формочки.Создадим собственный класс BatTestForm, который будет наследоваться от класса Form и содержать логику игры
# Класс формы с логикой class BatTestForm(Form): # Конструктор получает на вход переменную total - количество вопросов, на которые должен ответить ребенок def __init__(self, total): # Вызываем конструктор родителя super().__init__() # x - первый множитель self.x = 0 # y - второй множитель self.y = 0 # score - число ответов ребеонка self.score = 0 # total - количество правильных ответов, на которые должен ответить ребенок self.total = total # Метод повторной генерации множителей def update(self): # x - случайное целое число от 1 до 9 self.x = random.randint(1, 9) # y - случайное целое число от 1 до 9 self.y = random.randint(1, 9) # Отображаем надпись на формочке, типа x x y = self.label.setText(f"{self.x} x {self.y} = ") # обработчик нажатия кнопки def check(self): # z - ответ, введенныйв поле z = int(self.result.toPlainText().strip()) # Если ответ правильный if z == self.x * self.y: # увеличиваем счетчик правильных ответов self.score += 1 # Играем победную мелодию playsound("ok.wav", False) # Если можно продолжать игру дальше if self.score < self.total: # Диалоговое окошко показывает, что ответ правильный msg = QMessageBox() # Значок информационного окошка msg.setIcon(QMessageBox.Information) # Хвалим игррока=) msg.setText("Ты молодец!") # Хвалим еще сильнее! msg.setWindowTitle("Отлично!") # Диалоговое окошко имеет только кнопку OK msg.setStandardButtons(QMessageBox.Ok) # Показываем диалоговое окошко msg.exec_() # Очищаем поле ввода self.result.setText("") # Ставим курсов в поле ввода self.result.setFocus() # Генерируем следующий вопрос self.update() # Если конец игры (кончились попытки) else: # Диалоговое окошко сообщает о конце игры msg = QMessageBox() # Значок окошка с вопросом msg.setIcon(QMessageBox.Question) # Спрашиваем, будет ли игрок продолжать? msg.setText("Еще одну битву?") # Заголовок окошка msg.setWindowTitle("Конец битвы!") # Добавляем кнопки Ok и Cancel диалоговому окошку msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) # Отображаем окошко и сохраняем ответ пользователя res = msg.exec_() # Если игрок нажал Ok - обнуляем счетчик попыток и начинаем заново if res == QMessageBox.Ok: self.score = 0 self.result.setText("") self.result.setFocus() self.update() else: # Если игрок нажал Cancel - завершаем программу sys.exit(0) # Если ответ неправильный else: # Играем мелодию проигрыша playsound("error.wav", False) # Создаем окно ошибки m = QErrorMessage() # Текcт ошибки m.showMessage("Неправильно((( Давай еще разок") # Показываем ошибку m.exec_()
Из-за обилия комментариев код кажется длинным, но на самом деле все довольно просто. Обрабатываются 3 ситуации:
- Игрок ответил правильно;
- Игрок ответил неправильно;
- Конец игры.
Для нового вопроса есть метод update, который генерирует случайные множители.Для обработки ответа есть метод check, который проверяет ответ и реагирует в зависимости от результата.Осталось совсем немного: запустить приложениеВот и все, приложение можно запускать и звать игрока на битву с числами. Бэтмен ему поможет=) Итоговая структура проекта содержит код, формочку, 2 иконки и 2 аудио файла# Объект Qt приложения application = QApplication([]) # Главное окно window = Window() # Форма в главном окне form = BatTestForm(10) # Отображаем форму в окне form.setupUi(window) # Вызываем метод BatTestForm.update - генерируем первый вопрос form.update() # Связываем нажатие на кнопку и метод BatTestForm.check form.refresh.clicked.connect(form.check) # Показываем главное окно window.show() # Играем победную музыку playsound("ok.wav", False) # Запускаем приложение и ждем закрытия application.exec_()
battest ├── batman.png ├── error.wav ├── main.py ├── main.ui ├── ok.wav └── refresh.png
Заключение
Итак, с помощью Qt и Python мы немного разнообразили довольно скучный учебный процесс и внесли в него немного веселья. Исходный код проекта тут, можете менять его на свое усмотрение, я думаю, другие супергерои тоже не откажут в помощи вашему ребенку.
Хотя, не ограничивайтесь героями, я думаю такие злодеи как Танос - тоже смогут внушить школьнику любовь к математике!
До новых встреч!
Хотя, не ограничивайтесь героями, я думаю такие злодеи как Танос - тоже смогут внушить школьнику любовь к математике!
До новых встреч!
Комментариев нет:
Отправить комментарий