【PySide6】カルタの問題を読み上げてくれるだけのアプリを作る

はじめに

家族で国旗カルタを遊ぶためにただ問題をシャッフルして順番に読み上げてくれるだけのアプリを作りました。

音声ファイルはあらかじめOpen JTalkを使って問題の数だけ用意しました。

作り方は下記を参照して下さい。
touch-sp.hatenablog.com

使い方

python-vlcを使って音声ファイルを再生しています。あらかじめVLCのインストールが必要になります。

音声ファイルは「sounds」フォルダに入れています。

それぞれのファイル名は「〇〇(国名).wav」としています。最終的にその国名が解答として表示されます。

Pythonスクリプト

PySide6を使うとtime.sleepが使えなくなります。QEventLoopとQTimerで代用しています。

import glob
import random
import vlc
import os
from PySide6.QtCore import Qt, QSize, QEventLoop, QTimer
from PySide6.QtWidgets import QMainWindow, QApplication, QWidget, QLabel, QPushButton, QGridLayout, QSizePolicy

class Window(QMainWindow):

    sound_list = []
    sound_num = 0
    player = vlc.MediaPlayer()

    def __init__(self):
        super().__init__()    
        self.initUI()

    def initUI(self):
        self.setFixedSize(QSize(600, 300))
        self.setWindowTitle('カルタ')
        self.countryLabel = QLabel('開始')
        self.countryLabel.setAlignment(Qt.AlignCenter)
        self.countryLabel.setStyleSheet('font: 40px; font-weight: bold')

        self.startBtn = QPushButton('はじめ')
        self.startBtn.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.startBtn.setStyleSheet('font: 20px; font-weight: bold')
        self.startBtn.clicked.connect(self.push_startBtn)

        self.nextBtn = QPushButton('つぎのカード')
        self.nextBtn.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.nextBtn.setStyleSheet('font: 20px; font-weight: bold')
        self.nextBtn.setEnabled(False)
        self.nextBtn.clicked.connect(self.push_nextBtn)

        layout = QGridLayout()
        layout.addWidget(self.countryLabel, 0, 0, 1, 4)
        layout.addWidget(self.startBtn, 1, 0, 1, 1)
        layout.addWidget(self.nextBtn, 1, 1, 1, 3)

        mainWindow = QWidget()
        mainWindow.setLayout(layout)

        self.setCentralWidget(mainWindow)

    def push_startBtn(self):
        self.startBtn.setEnabled(False)
        self.nextBtn.setEnabled(True)
        self.countryLabel.setText('')

        self.sound_list = glob.glob('sounds/*.wav')
        self.sound_num = len(self.sound_list) - 1

        random.shuffle(self.sound_list)

    def push_nextBtn(self):
        self.nextBtn.setEnabled(False)
        self.countryLabel.setText('')
        self.Sound(self.sound_list[self.sound_num])
        country_name = os.path.splitext(os.path.basename(self.sound_list[self.sound_num]))[0]
        self.countryLabel.setText(country_name)
        self.sound_num -= 1
        if self.sound_num < 0:
            self.startBtn.setEnabled(True)
        else:
            self.nextBtn.setEnabled(True)
    
    def Sound(self, sound):
        playing_sound = vlc.Media(sound)
        self.player.set_media(playing_sound)
        self.player.play()
        
        loop = QEventLoop()
        QTimer.singleShot(800, loop.quit)
        loop.exec()

        duration = self.player.get_length()

        loop = QEventLoop()
        QTimer.singleShot(duration - 800, loop.quit)
        loop.exec()

if __name__ == "__main__":
    app = QApplication([])
    ex =Window()
    ex.show()
    app.exec()

動作環境

Windows 11
Python 3.10.5
PySide6==6.3.1
PySide6-Addons==6.3.1
PySide6-Essentials==6.3.1
python-vlc==3.0.16120
shiboken6==6.3.1

2022年7月15日追記

音声の再生にPySide6に含まれるQtMultimediaを使った新しいスクリプトを書きました。
touch-sp.hatenablog.com