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

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

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

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

Q&A

解決済

1回答

882閲覧

wxpythonを用いたGUIでトグルボタンの判定を繰り返し中に読み込みたい

zamichel

総合スコア7

Python 3.x

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

0グッド

2クリップ

投稿2017/10/28 15:35

wxpythonを用いたGUIを作成中です。
トグルボタンが押されている場合はループ処理を実行・
もう一度押されたら処理を停止する機能を実装したいです。
PushButton内のfor文内にてどのような処理を行えばトグルボタンの値を取得できるでしょうか。

###該当のソースコード

python

1 2import wx 3import time 4 5import gettext 6 7class MyFrame(wx.Frame): 8 def __init__(self, *args, **kwds): 9 kwds["style"] = wx.DEFAULT_FRAME_STYLE 10 wx.Frame.__init__(self, *args, **kwds) 11 self.button_1 = wx.ToggleButton(self, wx.ID_ANY, _("button")) 12 self.text_ctrl_4 = wx.TextCtrl(self, wx.ID_ANY, "text") 13 self.choice_2 = wx.Choice(self, wx.ID_ANY, choices=[_("1"), _("2"), _("3")]) 14 15 self.__set_properties() 16 self.__do_layout() 17 self.test = 1 18 self.Bind(wx.EVT_TOGGLEBUTTON, self.PushButton, self.button_1) 19 self.Bind(wx.EVT_TEXT_ENTER, self.EnterText, self.text_ctrl_4) 20 21 22 def __set_properties(self): 23 self.SetTitle(_("frame")) 24 self.choice_2.SetSelection(0) 25 26 def __do_layout(self): 27 sizer_16 = wx.BoxSizer(wx.VERTICAL) 28 sizer_17 = wx.BoxSizer(wx.VERTICAL) 29 sizer_17.Add(self.button_1, 0, 0, 0) 30 sizer_17.Add(self.text_ctrl_4, 0, 0, 0) 31 sizer_17.Add(self.choice_2, 0, 0, 0) 32 sizer_16.Add(sizer_17, 1, wx.EXPAND, 0) 33 self.SetSizer(sizer_16) 34 sizer_16.Fit(self) 35 self.Layout() 36 37 def PushButton(self, event): 38 for i in range(10): 39 self.test +=1 40 time.sleep(1) 41 button = self.button_1.GetValue() 42 43 if button: 44 print(self.test) 45 else: 46 break 47 48 def EnterText(self,event): 49 print(self.text_ctrl_4.GetValue()) 50 51class MyApp(wx.App): 52 def OnInit(self): 53 self.frame = MyFrame(None, wx.ID_ANY, "") 54 self.SetTopWindow(self.frame) 55 self.frame.Show() 56 return True 57 58 59if __name__ == "__main__": 60gettext.install("app") # replace with the appropriate catalog name 61 62 app = MyApp(0) 63 app.MainLoop()

###補足情報(言語/FW/ツール等のバージョンなど)
python3.6.1
wxpython

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

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

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

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

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

guest

回答1

0

ベストアンサー

質問に挙げたコードのように、ボタンを押したときのイベントハンドラ PushButton() 内でループを回してしまうと、イベントを行うスレッドが占有されてしまいます。その為、他のイベント処理を行うことが出来なくなり、結果アプリケーションが固まったような状態になります。
このようなGUIの動きを阻害するような時間のかかる処理は、イベントハンドラ内ではなく、別スレッド等でおこなうべきです。

今回のコードの場合は、1秒毎の処理を行っているだけのようだったので、forループ を インターバルタイマー(wx.Timer) での実装に簡易的に修正してみました。参考にしてみて下さい。

Python

1import wx 2import time 3 4import gettext 5 6class MyFrame(wx.Frame): 7 def __init__(self, *args, **kwds): 8 kwds["style"] = wx.DEFAULT_FRAME_STYLE 9 wx.Frame.__init__(self, *args, **kwds) 10 self.button_1 = wx.ToggleButton(self, wx.ID_ANY, _("button")) 11 self.text_ctrl_4 = wx.TextCtrl(self, wx.ID_ANY, "text") 12 self.choice_2 = wx.Choice(self, wx.ID_ANY, choices=[_("1"), _("2"), _("3")]) 13 14 self.__set_properties() 15 self.__do_layout() 16 self.test = 1 17 self.Bind(wx.EVT_TOGGLEBUTTON, self.PushButton, self.button_1) 18 self.Bind(wx.EVT_TEXT_ENTER, self.EnterText, self.text_ctrl_4) 19 20 # 以下を追加 21 self.timer = wx.Timer(self) 22 self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) 23 24 25 def __set_properties(self): 26 self.SetTitle(_("frame")) 27 self.choice_2.SetSelection(0) 28 29 def __do_layout(self): 30 sizer_16 = wx.BoxSizer(wx.VERTICAL) 31 sizer_17 = wx.BoxSizer(wx.VERTICAL) 32 sizer_17.Add(self.button_1, 0, 0, 0) 33 sizer_17.Add(self.text_ctrl_4, 0, 0, 0) 34 sizer_17.Add(self.choice_2, 0, 0, 0) 35 sizer_16.Add(sizer_17, 1, wx.EXPAND, 0) 36 self.SetSizer(sizer_16) 37 sizer_16.Fit(self) 38 self.Layout() 39 40 def PushButton(self, event): 41 """ 42 Button が Enableの時は Timer.Start()、 43 Disableの時は Time.Stop() 44 """ 45 if event.GetEventObject().GetValue(): 46 self.timer.Start(1000) # 1秒間隔(1000ms) 47 elif self.timer.IsRunning(): 48 self.timer.Stop() 49 50 def OnTimer(self, event): 51 """ 52 新規実装 53 Timer.Start() すると 1秒毎に呼ばれる 54 """ 55 self.test += 1 56 print(self.test) 57 58 def EnterText(self,event): 59 print(self.text_ctrl_4.GetValue()) 60 61class MyApp(wx.App): 62 def OnInit(self): 63 self.frame = MyFrame(None, wx.ID_ANY, "") 64 self.SetTopWindow(self.frame) 65 self.frame.Show() 66 return True 67 68 69if __name__ == "__main__": 70 gettext.install("app") # replace with the appropriate catalog name 71 72 app = MyApp(0) 73 app.MainLoop()

投稿2017/10/31 04:21

magichan

総合スコア15898

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問