PySimpleGUI
前回、PySimpleGUIでスピナーの設定(文字の色、背景色、フォントサイズ、複数選択)と選択項目を取得する方法を解説しました。
今回はスライダーの設定と値の取得方法を解説していきます。
それでは始めていきましょう。
スライダーの設置
スライダーを設置するには「sg.Slider」を用います。
その際、スライダの値を取得したり、逆にスライダーを移動させるため「key」をオプションに追加します。
そしてさらにスライダーの値の範囲として「range」を、初期値として「default_value」を、スライダーのステップの値(一つ動かした際に変化する量)として「resolution」を、スライダーの方向として「orientation」を追加します。
orientationは垂直方向として「v(verticalの頭文字)」、水平方向として「h(horizontalの頭文字)」の2種類があります。
import PySimpleGUI as sg
layout = [[sg.Slider(key='-hslider-', range=(0,100), default_value=50, resolution=1, orientation='h')],
[sg.Slider(key='-vslider-', range=(0,100), default_value=50, resolution=1, orientation='v')]]
window = sg.Window('Title', layout, size=(250,250))
event, values = window.read()
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
window.close()
スライダーの値の取得
スライダーの値は画面に表示する関係上、リアルタイムで取得することが多いことでしょう。
ということでまずは値をリアルタイムに取得して、その値を表示してみましょう。
リアルタイムに値を取得するので、「sg.Slider」のオプションに「enable_events=True」を追加します。
while文中で「event, values = window.read()」として値を取得している場合、選択した項目は「values[‘キー’]」で取得できます。
import PySimpleGUI as sg
layout = [[sg.Slider(key='-hslider-', range=(0,100), default_value=50, resolution=1, orientation='h', enable_events=True)],
[sg.Slider(key='-vslider-', range=(0,100), default_value=50, resolution=1, orientation='v', enable_events=True)],
[sg.Text('horizontal: 50', key='-htext-'), sg.Text('vartical: 50', key='-vtext-')]]
window = sg.Window('Title', layout, size=(250,250))
event, values = window.read()
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
window['-htext-'].update(f"horizontal: {values['-hslider-']}")
window['-vtext-'].update(f"vertical: {values['-vslider-']}")
window.close()
実行してスライダーを動かしてみると値がリアルタイムに変化します。
InputTextの数値と連動
またスライダーは入力欄に数値を入力し、その値にスライダーを変化させる、同時にスライダーを変化させると入力欄の数値が変動するといったようにスライダーと入力欄の連動も考えられます。
その際は入力欄に入力後に行うボタン操作とスライダー操作を「event」で受け取ります。
つまりそれぞれボタン操作の場合は入力欄の値を受け取り、スライダーの値の変化させ、逆にスライダー操作の場合はスライダーの値を受け取り、入力欄の値を変化させるということをします。
import PySimpleGUI as sg
layout = [[sg.Slider(key='-slider-', range=(0,100), default_value=50, resolution=1, orientation='h', enable_events=True)],
[sg.InputText(key='-textbox-', default_text='50')],
[sg.Button('Button', key='-button-')]]
window = sg.Window('Title', layout, size=(250,100))
event, values = window.read()
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
if event == '-button-':
window['-slider-'].update(values['-textbox-'])
if event == '-slider-':
window['-textbox-'].update(values['-slider-'])
window.close()
実行するとスライダーを動かした場合は入力欄の値も同じく変化し、また入力欄に数値を入力し「Button」をクリックした場合はスライダーがその値に変化します。
この時の注意点ですが、先ほどのリアルタイムに値を取得を取得する場合、値の取得とテキスト表示の変化には「if event == ‘-slider-‘:」とスライダー操作を実行したことを受け取るif文を入れなくても正しく動いていました。
しかしボタン操作とスライダー操作を連動させる場合、スライダー操作に対する「if event == ‘-slider-‘:」は必須になります。
その部分を抜かしたプログラムがこちらです。
import PySimpleGUI as sg
layout = [[sg.Slider(key='-slider-', range=(0,100), default_value=50, resolution=1, orientation='h', enable_events=True)],
[sg.InputText(key='-textbox-', default_text='50')],
[sg.Button('Button', key='-button-')]]
window = sg.Window('Title', layout, size=(250,100))
event, values = window.read()
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
if event == '-button-':
window['-slider-'].update(values['-textbox-'])
window['-textbox-'].update(values['-slider-'])
window.close()
このプログラムではスライダーを動かすと連動して入力欄の数字は変わります。
ここまでは想定した動作なのですが、次に入力欄に値を入力しボタンを押すと、スライダーが入力欄の値まで移動するのですが、入力欄の値はボタンを押す前のスライダーの値に変化します。
こちらの画像はスライダーを81まで動かしたのち、入力欄の値を25にしてボタンを押した時の結果です。
何故これが起こるのかというと、両方とも繰り返し中の1回の処理の中で行われます。
その時の値はwhile文の最初にある「event, values = window.read()」で決まります。
ボタンを押した時(if event == ‘-button-‘:)で、スライダーの値を入力欄の値に変化させます(window[‘-slider-‘].update(values[‘-textbox-‘]))。
そして続けて入力欄の値をスライダー欄の値に変化させてしまいます(window[‘-textbox-‘].update(values[‘-slider-‘]))。
しかもその値は「event, values = window.read()」で取得した値なので、入力欄の値に変化する前のスライダー欄の値です。
もし入力欄の値をスライダーの値に変化させるために「if event == ‘-slider-‘:」という条件分岐をしていたら、「window[‘-textbox-‘].update(values[‘-slider-‘])」は実行されず、両方とも入力欄の値になるというわけです。
なかなかややこしくて、私自身も混乱しましたが、処理をしっかり追うことで想定と違った動作をしたのかわかると思います。
これまでPySimpleGUIのウィジェットを色々と紹介してきましたが、これくらいのことを知っていれば、ある程度のアプリを作ることができるんじゃないかなと思います。
また使いそうなウィジェットがあれば適宜紹介することにして、とりあえずPySimpleGUIに関してはここまでとします。
次回はPythonでファイルかどうか、もしくはフォルダかどうかの判定を行う方法を紹介します。
ではでは今回はこんな感じで。
コメント