質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

984閲覧

変数を含む辞書内の値が更新されない

lteru

総合スコア6

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/09/07 14:18

Python初心者です。
PCのキープレスに応じて様々な波長の音を鳴らすアプリを作っています。
Tkinterを用いてキープレスを検出し、キーによって予め用意した辞書から値を取得しようとしています。
辞書内の値には変数を含めており、スケールバーの値によって辞書の値が変わるようにしたいですが、変数が更新されても辞書内の値が更新されません。

ソースコード

import tkinter as tk from tkinter import * import numpy as np #== Paramater bpm = 100 rate = 44100 DURATION = { 'L1': (60 / bpm * 4), # 全音符 'L2': (60 / bpm * 4) / 2, # 二分音符 'L4': (60 / bpm * 4) / 4, # 四分音符 'L8': (60 / bpm * 4) / 8, # 八分音符 } FREQ_SCALE = { 'ド/C4': 261.626, 'レ/D4': 293.665, 'ミ/E4': 329.628, } #== アプリケーションの定義 class Application(tk.Frame): def __init__(self, gain=0.25, rate=44100, chunk_size=1024, master=None): global bpm super().__init__(master) self.master = master self.master.title('Matplotlib in tkinter') self.pack() self.create_widgets() self.gain = gain self.rate = rate # サンプリング周波数"fs":44100 self.chunk_size = chunk_size #=== ウィジットの定義 def create_widgets(self): self.label_frame = tk.Frame(self.master) self.label_frame.pack(side=tk.LEFT) self.labelframe = tk.LabelFrame(self.label_frame, text="Push any key") self.labelframe.pack(anchor=tk.NW, padx=20) self.label = tk.Label(self.labelframe, text="Label", anchor=tk.W) self.label.pack() self.buffer = StringVar() self.buffer.set('xxx') self.press_key_label = tk.Label(self.labelframe, textvariable = self.buffer) self.press_key_label.pack() self.press_key_label.bind('<Any-KeyPress>', self.press_key) self.press_key_label.focus_set() #== Scale self.bpm = tk.DoubleVar() self.bpm.set(100) self.bpm_scale = tk.Scale(self.label_frame, variable=self.bpm, #変数 from_=10, #下限値 to=150, #上限値 resolution=1, #増減ステップ orient=tk.HORIZONTAL) self.bpm_scale.pack(anchor=tk.NW) def press_key(self, event): global duration, freq self.key = event.keysym if self.key == 'j': duration = DURATION['L8'] self.buffer.set('push key is %s' % self.key) elif self.key == 'k': duration = DURATION['L4'] self.buffer.set('push key is %s' % self.key) elif self.key == 'l': duration = DURATION['L2'] self.buffer.set('push key is %s' % self.key) elif self.key == 'semicolon': duration = DURATION['L1'] self.buffer.set('push key is %s' % self.key) bpm = self.bpm.get() print('bpm: %s' % bpm) print('duration: %s' % duration) print(DURATION) DURATION.update print(DURATION) print('freq: %s' % freq) # === メインウィンドウの作成 root = tk.Tk() #グラフデータ(初期) duration = DURATION['L4'] freq = FREQ_SCALE['ド/C4'] app = Application(master=root) root.mainloop()

該当のソースコード

DURATION = { 'L1': (60 / bpm * 4), # 全音符 'L2': (60 / bpm * 4) / 2, # 二分音符 'L4': (60 / bpm * 4) / 4, # 四分音符 'L8': (60 / bpm * 4) / 8, # 八分音符 class Application(tk.Frame): def __init__(self, gain=0.25, rate=44100, chunk_size=1024, master=None): global bpm #中略# #== Scale self.bpm = tk.DoubleVar() self.bpm.set(100) self.bpm_scale = tk.Scale(self.label_frame, variable=self.bpm, #変数 from_=10, #下限値 to=150, #上限値 resolution=1, #増減ステップ orient=tk.HORIZONTAL) self.bpm_scale.pack(anchor=tk.NW) def press_key(self, event): global duration, freq self.key = event.keysym if self.key == 'j': duration = DURATION['L8'] self.buffer.set('push key is %s' % self.key) elif self.key == 'k': duration = DURATION['L4'] self.buffer.set('push key is %s' % self.key) elif self.key == 'l': duration = DURATION['L2'] self.buffer.set('push key is %s' % self.key) elif self.key == 'semicolon': duration = DURATION['L1'] self.buffer.set('push key is %s' % self.key) bpm = self.bpm.get() #中略# DURATION.update print(DURATION) print('freq: %s' % freq)

試したこと

辞書内の変数bpmをグローバル変数で定義しましたが、"bpm = 100"をクラス内に配置するとエラーが出ました。
スケールバー設定後、bpmを更新するためにpress_key関数内で"bpm = self.bpm.get()"を記述することでbpmは更新されました。
しかし、辞書DURATIONの中身を見ると値は変わらないです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

  • 変数を含む辞書内の値が更新されない

そういう仕様です。

辞書は、値を定義するときに、その値を評価(計算)して値に格納します。
値として入れるものが変数を含む式であったとしても、それ以降に自動的に変更されることはありません。

変更したければ、変数が変更されるタイミングで変更するか、辞書の値を使いたいタイミングで再度計算するしかありません。

投稿2021/09/07 14:32

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問