前提・実現したいこと
PythonのTkinterで、以下のような機能を実現したいです。
- ボタンを押す
- ラベルを書き換える(歌詞を表示する)
- 音楽を再生する
発生している問題・エラーメッセージ
ボタンを押した後、音楽が鳴り終わった後にラベルが変更されてしまうので、ラベルを変更してから音楽が流れるようにしたい。
現状 | 目標 | |
---|---|---|
1 | ボタンを押す | ボタンを押す |
2 | 音楽の再生が始まる | ラベルを書き換える |
3 | 音楽の再生が終わる | 音楽の再生を始める |
4 | ラベルが変更される | 音楽の再生を終える |
該当のソースコード
ボタンを押すとplay_game
が呼び出されます。play_game
の中では、ラベルを変更する関数change_label
をthreadを用いて呼び出し、さらに音楽を再生する関数play_music
を呼び出しています。しかし、実際には音楽の再生→ラベルの変更の順で呼び出されてしまいます。
play_game
の中のlyric[1]
には歌詞(ラベルを書き換える文字)が、lyric[2]
lyric[3]
には音楽の再生したい部分の開始位置と終了位置(ミリ秒)が、lyric[5]
にはファイル名が入っています。
Python
1import sqlite3 2from pydub import AudioSegment 3from pydub.playback import play 4import tkinter as tk 5import threading 6 7 8def play_game(): 9 cur = conn.cursor() 10 cur.execute('SELECT * FROM lyrics ORDER BY RANDOM() LIMIT 1;') 11 lyric = cur.fetchone() 12 thread = threading.Thread(target=change_label, args=([lyric[1]])) 13 thread.start() # change_labelをthreadで呼び出し 14 play_music(lyric[2], lyric[3], lyric[5]) # play_musicを呼び出し 15 16 17def change_label(sub): # ラベルを変更する関数 18 sub_tk.set(sub) 19 20 21def play_music(start, end, title): # 音楽を再生する関数 22 sound = AudioSegment.from_mp3('./asset/mp3s/' + title + '.mp3') 23 sound = sound[start:end] 24 play(sound) 25 26 27dbname = 'data.db' 28conn = sqlite3.connect(dbname) 29 30root = tk.Tk() 31root.title('Label&Music') 32root.geometry("300x300") 33 34sub_tk = tk.StringVar() # ここにラベルを書き換える文字をセットする 35sub_tk.set('ここに歌詞が出力されます') 36 37subLabel = tk.Label(root, textvariable=sub_tk) # 書き換えるラベル 38subLabel.pack() 39 40playButton = tk.Button(root, text='再生') 41playButton['command'] = play_game # ボタンを押すとplay_game()を呼び出し 42playButton.pack() 43 44root.mainloop() 45 46conn.close() 47
試したこと
threadを試したのですがうまくいきませんでした。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/03/28 13:14