PyQt5 を使った足し算ドリルを改良した

touch-sp.hatenablog.com
子供の食いつきが悪かったので改良した。
前はPyQt5でのシリアル通信を使ったが今回はやめた。
あの時はArduino覚えたてで使いたかっただけ(笑)。はっきり言って不要。
f:id:touch-sp:20200816231616p:plain:w400
f:id:touch-sp:20200816231552p:plain:w400

注意

画像と音声のファイルを用意する必要があります。
数字の表示も画像を使っています。

Pythonスクリプト

import os
os.chdir(os.path.join(os.getcwd(), 'sound'))

import vlc
import random

import sys
from PyQt5 import QtCore, QtSerialPort
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QImage, QPixmap

############################################
max_num = 3
############################################

star_x_position = (110, 290, 470, 650, 830, 1010, 1190, 1370, 1550, 1730)
star_y_position = 20
ql_x_position = (170, 410, 650, 170, 410, 650, 170, 410, 650)
qr_x_position = (1130, 1370, 1610, 1130, 1370, 1610, 1130, 1370, 1610)
q_y_position = (140, 140, 140, 280, 280, 280, 420, 420, 420)
a_x_position = (25, 175, 325, 475, 625, 775, 925, 1075, 1225, 1375, 25, 175, 325, 475, 625, 775, 925, 1075, 1225, 1375)
a_y_position = (740, 740, 740, 740, 740, 740, 740, 740, 740, 740, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890)

star_image = QImage('star.png').scaled(80,80,QtCore.Qt.KeepAspectRatio)
image = QImage('donut.png').scaled(140,140,QtCore.Qt.KeepAspectRatio) 
num_image = [QImage('%d.png'%i).scaled(180,180,QtCore.Qt.KeepAspectRatio) for i in range(19)]
num_image_large = [QImage('%d_large.png'%i).scaled(240,240,QtCore.Qt.KeepAspectRatio) for i in range(19)]
num_image_red = [QImage('red%d.png'%i).scaled(240,240,QtCore.Qt.KeepAspectRatio) for i in range(19)]
purasu_image = QImage('purasu.png').scaled(180,180,QtCore.Qt.KeepAspectRatio)

player = vlc.MediaListPlayer()
mediaList = vlc.MediaList(['dummy.wav'])
player.set_media_list(mediaList)
player.play()

class Window(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()
        self.question = True
        self.q1 = 0
        self.q2 = 0
        self.real_answer = 0
        self.start_button_ready = True
        self.answer_button_ready = False
        self.your_answer = 0
        self.ok_count = 0

    def initUI(self):

        self.star_label = [QLabel(self) for i in range(10)]
        for i in range(10):
            self.star_label[i].setGeometry(QtCore.QRect(star_x_position[i], star_y_position, 80, 80))
            self.star_label[i].setFrameStyle(QFrame.Box | QFrame.Plain)
        
        self.question_left_label = [QLabel(self) for i in range(9)]
        self.question_right_label = [QLabel(self) for i in range(9)]
        
        for i in range(9):
            self.question_left_label[i].setGeometry(QtCore.QRect(ql_x_position[i], q_y_position[i], 140, 140))
        
        for i in range(9):
            self.question_right_label[i].setGeometry(QtCore.QRect(qr_x_position[i], q_y_position[i], 140, 140))

        self.answer_label = [QLabel(self) for i in range(20)]

        for i in range(20):
            self.answer_label[i].setGeometry(QtCore.QRect(a_x_position[i], a_y_position[i], 140, 140))

        self.question_left_pic = QLabel(self)
        self.question_left_pic.setGeometry(QtCore.QRect(650, 560, 180, 180))

        self.question_right_pic = QLabel(self)
        self.question_right_pic.setGeometry(QtCore.QRect(1130, 560, 180, 180))

        self.purasu_pic = QLabel(self)
        self.purasu_pic.setGeometry(QtCore.QRect(870, 560, 180, 180))

        self.real_answer_pic = QLabel(self)
        self.real_answer_pic.setGeometry(QtCore.QRect(1585, 760, 240, 240))

        self.your_answer_pic = QLabel(self)
        self.your_answer_pic.setGeometry(QtCore.QRect(1585, 530, 240, 240))

    def keyPressEvent(self, e):

        if e.key() == QtCore.Qt.Key_F and self.start_button_ready == True:
            
            #ボタンを無効にする
            self.start_button_ready = False

            if self.question == True: #問題作成モード
                
                # 画像の消去とパラメーターのリセット
                if self.ok_count == 10:
                    self.ok_count = 0
                    for i in range(10):
                        self.star_label[i].clear()

                for i in range(9):
                    self.question_left_label[i].clear()
                    self.question_right_label[i].clear()

                for i in range(20):
                    self.answer_label[i].clear()

                self.your_answer = 0
                self.your_answer_pic.setPixmap(QPixmap.fromImage(num_image_red[0]))
    
                #self.question_left_pic.clear()
                #self.question_right_pic.clear()
                #self.purasu_pic.clear()
                self.real_answer_pic.clear()

                # 問題の作成
                self.q1 = random.randint(1, max_num)
                self.q2 = random.randint(1, max_num)
                self.real_answer = self.q1 + self.q2

                # 画像の表示
                for i in range(self.q1):
                    self.question_left_label[i].setPixmap(QPixmap.fromImage(image))

                for i in range(self.q2):
                    self.question_right_label[i].setPixmap(QPixmap.fromImage(image))

                self.question_left_pic.setPixmap(QPixmap.fromImage(num_image[self.q1]))
                self.question_right_pic.setPixmap(QPixmap.fromImage(num_image[self.q2]))
                self.purasu_pic.setPixmap(QPixmap.fromImage(purasu_image))

                # 音の再生
                sound_list = []
                sound_list.append(str(self.q1) + '.wav')
                sound_list.append('dummy_short.wav')
                sound_list.append('tasu.wav')
                sound_list.append('dummy_short.wav')
                sound_list.append(str(self.q2) + '.wav')

                mediaList = vlc.MediaList(sound_list)
                player.set_media_list(mediaList)
                player.play()

                loop = QtCore.QEventLoop()
                QtCore.QTimer.singleShot(3000, loop.quit)
                loop.exec_()

                self.question = False

                self.start_button_ready = True
                self.answer_button_ready = True

            else: #解答表示モード

                self.answer_button_ready = False

                # 画像の移動
                count = 0
                for i in range(0, self.q1):
                    self.question_left_label[i].clear()
                    self.answer_label[count].setPixmap(QPixmap.fromImage(image))

                    self.real_answer_pic.setPixmap(QPixmap.fromImage(num_image_large[count+1]))
                    
                    mediaList = vlc.MediaList([str(count+1)+'.wav'])
                    player.set_media_list(mediaList)
                    player.play()

                    loop = QtCore.QEventLoop()
                    QtCore.QTimer.singleShot(1000, loop.quit)
                    loop.exec_()

                    count += 1

                for i in range(0, self.q2):
                    self.question_right_label[i].clear()
                    self.answer_label[count].setPixmap(QPixmap.fromImage(image))

                    self.real_answer_pic.setPixmap(QPixmap.fromImage(num_image_large[count+1]))

                    mediaList = vlc.MediaList([str(count+1)+'.wav'])
                    player.set_media_list(mediaList)
                    player.play()

                    loop = QtCore.QEventLoop()
                    QtCore.QTimer.singleShot(1000, loop.quit)
                    loop.exec_()

                    count += 1

                #正誤の判定
                sound_list = []
                wait_time = 1800
                if self.your_answer == self.real_answer:
                    sound_list.append('ok.wav')
                    self.ok_count += 1
                    self.star_label[self.ok_count-1].setPixmap(QPixmap.fromImage(star_image))
                    if self.ok_count ==10:
                        wait_time = 2500
                        sound_list.append('dummy_short.wav')
                        sound_list.append('yattane.wav')
                else:
                    sound_list.append('boo.wav')
                
                mediaList = vlc.MediaList(sound_list)
                player.set_media_list(mediaList)
                player.play()

                loop = QtCore.QEventLoop()
                QtCore.QTimer.singleShot(wait_time, loop.quit)
                loop.exec_()

                self.question = True
                
                self.start_button_ready = True

        if e.key() == QtCore.Qt.Key_A and self.answer_button_ready==True:
            if self.your_answer > 0:
                self.your_answer -= 1
            self.your_answer_pic.setPixmap(QPixmap.fromImage(num_image_red[self.your_answer]))

        if e.key() == QtCore.Qt.Key_D and self.answer_button_ready==True:
            if self.your_answer < 18:
                self.your_answer += 1
            self.your_answer_pic.setPixmap(QPixmap.fromImage(num_image_red[self.your_answer]))
            
        # エスケープキーを押すと画面が閉じる
        if e.key() == QtCore.Qt.Key_Escape:
            self.close()

app = QApplication(sys.argv)
ex =Window()

ex.showFullScreen()
sys.exit(app.exec_())