PyQt5 で QLabel のグループ化 - パソコン関連もろもろ
PyQt5 を使って Arduino とシリアル通信 - パソコン関連もろもろ
PyQt5 で python-vlc を扱う - パソコン関連もろもろ
上記で習得したスキルを使って子供のための計算ドリルを作ってみた。
Pythonスクリプト
import os os.chdir(os.path.join(os.getcwd(), 'sound')) import vlc import time import random import sys from PyQt5 import QtCore, QtSerialPort from PyQt5.QtWidgets import * from PyQt5.QtGui import QImage, QPixmap ############################################ max_num = 5 ############################################ 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 = (80, 80, 80, 240, 240, 240, 400, 400, 400) 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) 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.answer = 0 self.button_ready = True self.serial = QtSerialPort.QSerialPort( 'COM5', baudRate=QtSerialPort.QSerialPort.Baud9600, readyRead = self.receive) self.serial.open(QtCore.QIODevice.ReadWrite) time.sleep(1.5) def initUI(self): self.label_list_left = [QLabel(self) for i in range(9)] self.label_list_right = [QLabel(self) for i in range(9)] for i in range(9): self.label_list_left[i].setGeometry(QtCore.QRect(ql_x_position[i], q_y_position[i], 140, 140)) for i in range(9): self.label_list_right[i].setGeometry(QtCore.QRect(qr_x_position[i], q_y_position[i], 140, 140)) self.label_answer = [QLabel(self) for i in range(20)] self.question_left_pic = QLabel(self) self.question_left_pic.setGeometry(QtCore.QRect(390, 540, 180, 180)) self.question_right_pic = QLabel(self) self.question_right_pic.setGeometry(QtCore.QRect(1350, 540, 180, 180)) self.purasu_pic = QLabel(self) self.purasu_pic.setGeometry(QtCore.QRect(870, 540, 180, 180)) self.label_answer_pic = QLabel(self) self.label_answer_pic.setGeometry(QtCore.QRect(1625, 800, 180, 180)) for i in range(20): self.label_answer[i].setGeometry(QtCore.QRect(a_x_position[i], a_y_position[i], 160, 160)) def receive(self): #ボタンが無効なら何もしない if self.button_ready == False: dummy = self.serial.readAll() else: dummy = self.serial.readAll() #ボタンを無効にする self.button_ready = False if self.question == True: # 画像の消去 for i in range(9): self.label_list_left[i].clear() self.label_list_right[i].clear() for i in range(20): self.label_answer[i].clear() self.question_left_pic.clear() self.question_right_pic.clear() self.purasu_pic.clear() self.label_answer_pic.clear() # 問題の作成 self.q1 = random.randint(1, max_num) self.q2 = random.randint(1, max_num) self.answer = self.q1 + self.q2 # 画像の表示 for i in range(self.q1): self.label_list_left[i].setPixmap(QPixmap.fromImage(image)) for i in range(self.q2): self.label_list_right[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 else: # 画像の移動 count = 0 for i in range(0, self.q1): self.label_list_left[i].clear() self.label_answer[count].setPixmap(QPixmap.fromImage(image)) self.label_answer_pic.setPixmap(QPixmap.fromImage(num_image[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.label_list_right[i].clear() self.label_answer[count].setPixmap(QPixmap.fromImage(image)) self.label_answer_pic.setPixmap(QPixmap.fromImage(num_image[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 = [] sound_list.append('dummy_short.wav') sound_list.append('seikai.wav') sound_list.append('dummy_short.wav') sound_list.append(str(self.answer) + '.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 = True #ボタンを有効に戻す self.button_ready = True def keyPressEvent(self, e): # エスケープキーを押すと画面が閉じる if e.key() == QtCore.Qt.Key_Escape: self.close() 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)] purasu_image = QImage('purasu.png').scaled(180,180,QtCore.Qt.KeepAspectRatio) app = QApplication(sys.argv) ex =Window() ex.showFullScreen() sys.exit(app.exec_())
Arduinoスケッチ
const int buttonON = LOW; // ボタンが押されているとピンの値はLOW const int buttonOFF = HIGH; // ボタンが押されていないとピンの値はHIGH const int buttonPin = 2; int buttonState; void setup() { Serial.begin(9600); pinMode(buttonPin, INPUT_PULLUP); } void loop() { buttonState = digitalRead(buttonPin); if (buttonState == buttonON) { // ボタンが押されていたら Serial.write(255); delay(1500); } }