PythonでGUI wxPython サンプルプログラム

2020-08-03

プログラミング言語Python(パイソン)に関する話です。

初心者向けにwxPythonでサンプルプログラムを作ってみました。

ソースコードは下に記載します。

↑実行ボタンをクリックすると、以下の画面を表示します。↓

で、これだとそこそこ長いプログラムになりますので、少しずつ進みたいという方は以下をどうぞ。

wxPython入門

確認環境

  • Windows 10 Home(64bit)
  • Python 3.8.2(64bit)
  • wxPython 4.7.2.post2

サンプルプログラム画面

特に何をするというプログラムでもないのですが、プログラム、wxPython、GUI初心者など誰かの役に立てばいいなと思った次第です。

[実行]ボタンをクリックすると、入力内容を表示します。

[ファイル選択]ボタン右のファイル名の指定は以下の3つの方法に対応しています。

  • 自分で入力
  • [ファイル選択]ボタンの選択ダイヤログから選択
  • ファイル名入力欄へのDnD(ドラッグアンドドロップ)

誰か見ているようだったら(需要があるようなら)メニューバーやファイルのRead/Writeその他の機能を追加します。

不明点や要望あればコメント願います。

サンプルプログラムソース

################################################################################
#履歴
# Ver.1.00.00	新規作成
################################################################################
import wx
import os

gWinTitle = "入力内容を表示するだけのプログラム"				#ウィンドウタイトル
gWinWidth = 500									#ウィンドウの横幅
gWinHeight = 600								#ウィンドウの高さ

gTbWidth = 350    								#入力コントロールの幅
gTbHeight = 40

################################################################################
#項目名その他キャプション
################################################################################
#1行目 チェックボックス
item010_01 = " 項目1"
item010_02 = "チェックボックスの選択肢"
item010_tooltip = "チェックボックスのツールチップです"

#2行目 ラジオボタン
item020_01 = " 項目2"
item020_02 = "ラジオボタン"
item020_03 = "ラジオボタン選択肢1"
item020_04 = "ラジオボタン選択肢2"
item020_tooltip = "ラジオボタンのツールチップです"

#3行目 1行テキスト
item030_01 = " 項目3"
item030_02 = "1行テキスト"

#4行目 プルダウン
item040_01 = " 項目4"
item040_02 = "1行リスト"
item040_03 = "1行リスト選択肢1"
item040_04 = "1行リスト選択肢2"
item040_05 = "1行リスト選択肢3"

#5行目 リスト
item050_01 = " 項目5"
item050_02 = "複数行リスト"
item050_03 = "複数行リスト選択肢1"
item050_04 = "複数行リスト選択肢2"
item050_05 = "複数行リスト選択肢3"

#6行目 コンボボックス
item060_01 = " 項目6"
item060_02 = "コンボボックス"
item060_03 = "コンボボックス選択肢1"
item060_04 = "コンボボックス選択肢2"
item060_05 = "コンボボックス選択肢3"

#7行目 複数行テキスト
item070_01 = " 項目7"
item070_02 = "複数行テキスト1行目\n複数行テキスト2行目\n複数行テキスト3行目"

#8行目 1行テキスト
item080_01 = "ファイル選択"
item080_02 = "選択したファイル名が入ります"

#ボタンキャプション
item_run = "実行"
item_exit = "終了"

################################################################################
#自作Appクラス
#追加したい処理があれば追加します
################################################################################
class MyApp(wx.App):								#wx.Appを継承
    def OnInit(self):
        return True

################################################################################
#フレームクラス
#追加したい処理があれば追加します
################################################################################
class MyFrame1(wx.Frame):							#wx.Frameを継承
    ############################################################################
    #初期化処理
    #・フレームの作成
    #・終了イベントの関連付け
    ############################################################################
    def __init__(self, parent):                                                 #フレーム作成時に呼び出されます
        wx.Frame.__init__ (self, None, -1, gWinTitle, size=(gWinWidth, gWinHeight))     #ウィンドウタイトルとウィンドウサイズをセットします
        self.Bind(wx.EVT_CLOSE, self.frame_close)

    def __del__( self ):
        pass

    ############################################################################
    #終了時に発生するイベント
    ############################################################################
    def frame_close(self, event):
        ret = wx.MessageBox(u"終了ボタンがクリックされました。\n終了します。よろしいですか?", u"終了確認", style = wx.YES_NO)
        if ret == wx.YES:
            #データの保存など終了前の処理が必要な場合はここにいれるのがよいでしょう
            wx.MessageBox(u"「はい」が選択されました", u"確認", wx.ICON_INFORMATION)
            self.Destroy()
        elif ret == wx.NO:
            wx.MessageBox(u"「いいえ」が選択されました", u"確認", wx.ICON_INFORMATION)

################################################################################
#ドロップを受け取るクラスの定義
################################################################################
class MyFileDropTarget1(wx.FileDropTarget):
    def __init__(self, window):
        wx.FileDropTarget.__init__(self)
        self.window = window							#ファイルをドロップする対象

    def OnDropFiles(self, x, y, filenames):					#ファイルをドロップするときの処理
        for file in filenames:
            Content080.SetValue(file)
        return True

################################################################################
#対象ファイル選択
################################################################################
def select_target(event):
    # 選択可能なファイルを制限する
    filter = "python file(*.exe;) | *.exe; | All file(*.*) | *.*"
    dialog = wx.FileDialog(None, u'対象ファイルを選択してください', '', '', filter)
    if dialog.ShowModal() != wx.ID_CANCEL:                                      #ファイル選択ダイアログを表示 キャンセルじゃなければ次に進む
        Content080.SetValue(dialog.GetPath())                                   #選んだファイルをファイル名入力欄にせっと

################################################################################
#チェックボックス操作時の処理
################################################################################
def do_check_function(event):
    if True == Content010.IsChecked():
        wx.MessageBox(u"チェックされました", u"確認", wx.ICON_INFORMATION)
    else:
        wx.MessageBox(u"チェックがはずされました", u"確認", wx.ICON_INFORMATION)

################################################################################
#ラジオボタン操作時の処理
################################################################################
def do_radio_function(event):
    ############################################################################
    #選択値の取得
    ############################################################################
    radioSel = Content020.GetStringSelection()
    if "ラジオボタン選択肢1" == radioSel:
        wx.MessageBox(u"「ラジオボタン選択肢1」が選択されました", u"確認", wx.ICON_INFORMATION)
    elif "ラジオボタン選択肢2" == radioSel:
        wx.MessageBox(u"「ラジオボタン選択肢2」が選択されました", u"確認", wx.ICON_INFORMATION)
    else:
        wx.MessageBox(u"例外 その他の選択肢が選択されました", u"確認", wx.ICON_INFORMATION)

################################################################################
#コンボ選択テキスト入力時の動作
################################################################################
def text1_input_function(event):
    ############################################################################
    #選択値の取得
    ############################################################################
    text1Input = Content030.GetStringSelection()
    wx.MessageBox(u"「項目3」のテキスト入力が変更されました\n入力しづらくてすみません", u"確認", wx.ICON_INFORMATION)

################################################################################
#1行リスト選択肢変更時の動作
################################################################################
def combo1_change_function(event):
    ############################################################################
    #選択値の取得
    ############################################################################
    combo1Sel = Content040.GetStringSelection()
    
    if item040_03 == combo1Sel:
        wx.MessageBox(u"「" + item040_03 + "」が選択されました", u"確認", wx.ICON_INFORMATION)
    elif item040_04 == combo1Sel:
        wx.MessageBox(u"「" + item040_04 + "」が選択されました", u"確認", wx.ICON_INFORMATION)
    elif item040_05 == combo1Sel:
        wx.MessageBox(u"「" + item040_05 + "」が選択されました", u"確認", wx.ICON_INFORMATION)
    else:
        wx.MessageBox(u"例外 その他の選択肢が選択されました", u"確認", wx.ICON_INFORMATION)

    #単純に以下のようにすることも可能です
#    wx.MessageBox(u"「" + list1Sel + "」が選択されました", u"確認", wx.ICON_INFORMATION)

################################################################################
#複数行行リスト選択肢変更時の動作
################################################################################
def list1_change_function(event):
    ############################################################################
    #選択値の取得
    ############################################################################
    list1Sel = Content050.GetStringSelection()
    
    wx.MessageBox(u"「" + list1Sel + "」が選択されました", u"確認", wx.ICON_INFORMATION)

    #以下のようにしても「大体」同じです
#    if item050_03 == list1Sel:
#        wx.MessageBox(u"「" + item050_03 + "」が選択されました", u"確認", wx.ICON_INFORMATION)
#    elif item050_04 == list1Sel:
#        wx.MessageBox(u"「" + item050_04 + "」が選択されました", u"確認", wx.ICON_INFORMATION)
#    elif item050_05 == list1Sel:
#        wx.MessageBox(u"「" + item050_05 + "」が選択されました", u"確認", wx.ICON_INFORMATION)
#    else:
#        wx.MessageBox(u"例外 その他の選択肢が選択されました", u"確認", wx.ICON_INFORMATION)

################################################################################
#コンボ選択肢変更時の動作
################################################################################
def combo2_change_function(event):
    ############################################################################
    #選択値の取得
    ############################################################################
    combo2Sel = Content060.GetStringSelection()
    wx.MessageBox(u"「項目6」の選択値が変更されました\n詳細省略", u"確認", wx.ICON_INFORMATION)

################################################################################
#コンボ選択テキスト入力時の動作
################################################################################
def combo2_input_function(event):
    ############################################################################
    #選択値の取得
    ############################################################################
#    combo2Sel = Content060.GetStringSelection()
#    wx.MessageBox(u"「項目6」のテキスト入力が変更されました\n入力しづらくてすみません", u"確認", wx.ICON_INFORMATION)
    pass

################################################################################
#テキスト入力時の動作
################################################################################
def combo3_input_function(event):
    ############################################################################
    #他と大体同じなので省略
    ############################################################################
    pass

################################################################################
#実行ボタン
################################################################################
def run_button_function(event):							#実行ボタンをクリック時の動作
#    wx.MessageBox(u"実行ボタンをクリックしました\n入力内容を確認します", u"確認", wx.ICON_INFORMATION)
    
    outText = "「項目1」\n"
    if True == Content010.IsChecked():
        outText += "チェックあり\n\n"
    else:
        outText += "チェックなし\n\n"

    outText += "「項目2」\n"
    radioSel = Content020.GetStringSelection()                                  #一回変数に格納してから
    outText += radioSel + "\n\n"                                                #代入したり

    outText += "「項目3」\n"
    outText += Content030.GetValue() + "\n\n"                                   #変数に入れずに代入したり

    outText += "「項目4」\n" + Content040.GetValue() + "\n\n"                  #1行で書いてみたり

    outText += "「項目5」\n" + Content050.GetStringSelection() + "\n\n"

    outText += "「項目6」\n" + Content060.GetValue() + "\n\n"

    outText += "「項目7」\n" + Content070.GetValue() + "\n\n"

    outText += "「ファイル名」\n" + Content080.GetValue() + "\n\n"

    wx.MessageBox(u"★入力内容確認★\n\n" + outText, u"確認", wx.ICON_INFORMATION)


################################################################################
#メイン処理
################################################################################
if __name__ == '__main__':
    window = MyApp(0)								# wxPythonのGUI Appインスタンスを生成 (= GUI Appを初期化)
    frame = MyFrame1(None)		                                        # フレーム作成(ウィンドウタイトルとウィンドウサイズを指定)
    panel = wx.Panel(frame, -1)							# ボタンやテキストボックスを配置するためのパネルを作成

    ############################################################################
    #コントロールの定義
    #タイトルバー左の画像(アイコン)を設定したい場合は以下を有効にしてください
    ############################################################################
#    gSettingIco = "C:\\python\\sample\\icon.ico"
#    icon = wx.Icon(gSettingIco, wx.BITMAP_TYPE_ICO)
#    frame.SetIcon(icon)

    ############################################################################
    #コントロールの定義
    ############################################################################
    #先頭余白(レイアウト調整用)
    labelEmpty010 = wx.StaticText(panel, wx.ID_ANY, '')
    labelEmpty020 = wx.StaticText(panel, wx.ID_ANY, '')

    #項目1の設定(チェックボックス)
    label010 = wx.StaticText(panel, wx.ID_ANY, item010_01)                      #「項目1」
    Content010 = wx.CheckBox(panel, wx.ID_ANY, item010_02)			#「チェックボックス選択肢」
    Content010.SetToolTip(item010_tooltip)                                      #チェックボックスのツールチップ(マウスカーソルを合わせると表示されます)

    #項目2の設定(ラジオボタン)
    label020 = wx.StaticText(panel, wx.ID_ANY, item020_01)                      #「項目2」
    radio_array = (item020_03, item020_04)                                      #ラジオボタンの選択肢
    Content020 = wx.RadioBox(panel, wx.ID_ANY, item020_02, choices=radio_array, style=wx.RA_HORIZONTAL)
    Content020.SetToolTip(item020_tooltip)                                      #ラジオボタンのツールチップ(マウスカーソルを合わせると表示されます)

    #項目3の設定(1行テキスト)
    label030 = wx.StaticText(panel, wx.ID_ANY, item030_01)
    Content030 = wx.TextCtrl(panel, wx.ID_ANY, size=(gTbWidth, -1))

    #項目4の設定(リスト)
    label040 = wx.StaticText(panel, wx.ID_ANY, item040_01)
    combo_array040 = (item040_03, item040_04, item040_05)
    Content040 = wx.ComboBox(panel, wx.ID_ANY, '', size=(gTbWidth, -1), choices=combo_array040, style=wx.CB_READONLY)

    #項目5の設定(リスト)
    label050 = wx.StaticText(panel, wx.ID_ANY, item050_01)
    list_array050 = (item050_03, item050_04, item050_05)
    Content050 = wx.ListBox(panel, wx.ID_ANY, choices=list_array050, style=wx.LB_SINGLE)

    #項目6の設定(コンボボックス)
    label060 = wx.StaticText(panel, wx.ID_ANY, item060_01)
    combo_array060 = (item060_03, item060_04, item060_05)
    Content060 = wx.ComboBox(panel, wx.ID_ANY, '', size=(gTbWidth, -1), choices=combo_array060, style=wx.CB_DROPDOWN)

    #項目7の設定(複数行のテキストエリア)
    label070 = wx.StaticText(panel, wx.ID_ANY, item070_01)
    Content070 = wx.TextCtrl(panel, wx.ID_ANY, size=(gTbWidth, gTbHeight), style=wx.TE_MULTILINE)
    Content070.SetValue(item070_02)

    #ファイル選択
    fsel_button = wx.Button(panel, wx.ID_ANY, label=item080_01)                 #ファイル選択ボタン
    Content080 = wx.TextCtrl(panel, wx.ID_ANY, size=(gTbWidth, -1))             #ファイル名入力欄

    #ボタン上空白行(レイアウト調整用)
    labelEmpty090 = wx.StaticText(panel, wx.ID_ANY, '')
    labelEmpty091 = wx.StaticText(panel, wx.ID_ANY, '')

    #実行ボタン
    labelEmpty100 = wx.StaticText(panel, wx.ID_ANY, '')
    run_button = wx.Button(panel, wx.ID_ANY, label=item_run)		        #実行ボタンの作成

    #終了ボタン
    labelEmpty110 = wx.StaticText(panel, wx.ID_ANY, '')
    exit_button = wx.Button(panel, wx.ID_ANY, label=item_exit)		        #終了ボタンの作成

    ############################################################################
    #コントロールの初期値設定
    ############################################################################
    Content030.SetValue("1行テキストの入力欄です")
    Content060.SetValue("選択肢にない文字列も入力可能です")
    Content080.SetValue("ファイル名入力欄です。ドラッグアンドドロップ可能です")

    ############################################################################
    #コントロールと関数の関連付け
    #ここより前に初期値のセットSetValue()をするのがよいでしょう
    #ここより後ろで初期値をセットすると関連付けた関数が呼ばれてしまいます
    ############################################################################
    Content010.Bind(wx.EVT_CHECKBOX, do_check_function)  		        #チェックボックス操作と関数をひもづける
    Content020.Bind(wx.EVT_RADIOBOX, do_radio_function)  		        #ラジオボタン操作と関数をひもづける
    Content030.Bind(wx.EVT_TEXT, text1_input_function)  		        #テキスト入力と関数をひもづける
    Content040.Bind(wx.EVT_COMBOBOX, combo1_change_function)  		        #リスト操作と関数をひもづける
    Content050.Bind(wx.EVT_LISTBOX, list1_change_function)  		        #リスト操作と関数をひもづける
    Content060.Bind(wx.EVT_COMBOBOX, combo2_change_function)  		        #リスト操作(選択)と関数をひもづける
    Content060.Bind(wx.EVT_TEXT, combo2_input_function)  		        #リスト操作(入力)と関数をひもづける
    Content070.Bind(wx.EVT_TEXT, combo3_input_function)  		        #テキスト入力と関数をひもづける

    fsel_button.Bind(wx.EVT_BUTTON, select_target)  				#ファイル選択押下と関数をひもづける
    run_button.Bind(wx.EVT_BUTTON, run_button_function)  		        #実行ボタン押下と関数をひもづける
    exit_button.Bind(wx.EVT_BUTTON, frame.frame_close)  		        #終了ボタン押下と関数をひもづける

    ############################################################################
    #コントロールの配置
    #項目の増減があった場合は、rowsとcolsも変更してください
    ############################################################################
    panel.SetBackgroundColour('#AFAFAF')
    layout = wx.FlexGridSizer(rows=12, cols=2, gap=(5, 5))			#rows=9, cols=2の場合は9行2列のレイアウトということ

    layout.Add(labelEmpty010, flag=wx.GROW)					#先頭余白
    layout.Add(labelEmpty020, flag=wx.GROW)					#先頭余白

    #チェックボックスを追加
    layout.Add(label010, flag=wx.GROW)				        	#
    layout.Add(Content010)						        #

    #ラジオボタンを追加
    layout.Add(label020, flag=wx.GROW)				        	#
    layout.Add(Content020)						        #
    
    #1行テキストを追加
    layout.Add(label030, flag=wx.GROW)				        	#
    layout.Add(Content030)						        #
    
    #1行リストを追加
    layout.Add(label040, flag=wx.GROW)				        	#
    layout.Add(Content040)						        #
    
    #複数行リストを追加
    layout.Add(label050, flag=wx.GROW)				        	#
    layout.Add(Content050)						        #
    
    #コンボボックスを追加
    layout.Add(label060, flag=wx.GROW)				        	#
    layout.Add(Content060)						        #
    
    #複数行テキストを追加
    layout.Add(label070, flag=wx.GROW)				        	#
    layout.Add(Content070)						        #

    #ファイル選択ボタンとファイル名入力欄
    layout.Add(fsel_button, flag=wx.SHAPED | wx.ALIGN_RIGHT)			#
    layout.Add(Content080)							#

    #空白行(レイアウト調整用)
    layout.Add(labelEmpty090, flag=wx.GROW)					#ボタン上余白
    layout.Add(labelEmpty091, flag=wx.GROW)					#ボタン上余白

    #実行ボタン
    layout.Add(labelEmpty100, flag=wx.GROW)					#空白
    layout.Add(run_button, flag=wx.SHAPED | wx.ALIGN_RIGHT)			#実行ボタン

    #終了ボタン
    layout.Add(labelEmpty110, flag=wx.GROW)					#空白
    layout.Add(exit_button, flag=wx.SHAPED | wx.ALIGN_RIGHT)			#終了ボタン

    #ここまでの設定を反映
    panel.SetSizer(layout)							#レイアウト設定

    #ドラッグアンドドロップの設定
    dt1 = MyFileDropTarget1(Content080)						#ドロップする対象を「ファイル名入力欄」にする
    Content080.SetDropTarget(dt1)
    #ドロップする対象を画面全体にしたい場合は以下を採用してください
#    dt1 = MyFileDropTarget1(panel)						#ドロップする対象をこのフレーム全体にする
#    panel.SetDropTarget(dt1)

    ############################################################################
    #
    ############################################################################
    frame.Show()								#フレーム表示
    window.MainLoop()								#イベント待機

多くの人が見ているわけでもありませんし、そんなに気合入れて作っていませんが、「ここはこうした方がいいでしょ」というのがあれば、遠慮なく優しくコメント願います。

変数名についてはご勘弁を。

参考サイト

以上。

後記

最後までお読みくださりありがとうございます。

こんなに更新したのに、現在はほぼ誰も見ていないゴミカスクズ無価値ブログです。

よければ(はてな)ブックマークや拡散をお願いいたします。

更新の原動力として励ましが欲しいのです…<(_ _)>

当ブログ内お薦め記事