【Python】wxPythonを使ってフォルダ選択ダイアログを作成してみた

　　
　　
　　
**この記事はPythonど素人が趣味で適当に書いたものです。
そのつもりでお読みください。あと助けて下さい。**

##wxPythonとは？
GUIアプリケーション作成ツールです。
使い方とかもろもろ[【こちら】](https://qiita.com/Kodaira_/items/c073ddc400309d871150)で網羅できました。ありがとうございます。

##フォルダ選択ダイアログ
よく見かける[参照]を押したらフォルダを選択できるダイアログが出てくるアレです。

最終的に選択した2種類のフォルダの中身を比較し、
中身の異なるフォルダを片方に移動＆削除までやりたいです。
(まだできてないのでこの記事はフォルダ選択ダイアログを表示して終わります)

##Windowを作成
`Frame(枠)`-`Panel(UIを置くパネル)`-`Button(押したら何かしら起きるボタン)`
の順番に作ります。

###Frame(枠)

これで枠ができました。

```python
import wx

class Main(wx.Frame):

    def __init__(self, parent, id, title):
       
        wx.Frame.__init__(self, parent, id, title, size=(500, 300))
```
`__init__`はPythonのコンストラクタらしいです。
`class Main(wx.Frame)`←ここではFrameクラスを継承してるっぽいです。
現時点でわかったのはここまでです。

`wx.Frame.__init__`
↑間違えているかもしれませんがFrameクラスのコンストラクタであると解釈しました。

以下、wxPythonの公式ドキュメントに記載されていた`__init__`です。
>`__init__ (self, parent, id=ID_ANY, pos=DefaultPosition, size=DefaultSize, style=TAB_TRAVERSAL, name=PanelNameStr)`


###Panel(UIを置くパネル)
これでパネルができました。

```python
panel = wx.Panel(self, id=wx.ID_ANY)
```
以下、wxPythonの公式ドキュメントに記載されていた`wx.Panel`です。
>`Panel(parent, id=ID_ANY, pos=DefaultPosition, size=DefaultSize,
      style=TAB_TRAVERSAL, name=PanelNameStr)`

これを見た感じだと、
第一引数に当たる`self`には先程作ったFrameが、
第二引数にはidは何でもいいですよという意味に当たる`wx.ID_ANY`が入っている
みたいなところでしょうか。

つまり、Panelの親はFrameですよってことなんでしょうきっと、うん。

###Button(押したら何かしら起きるボタン)
二つのボタンができました。(ついでにボタンの説明も追加してます)


```Python
        # 旧プロジェクトファイル選択ボタン
        wx.StaticText(panel, wx.ID_ANY, label="旧プロジェクト", pos=(10, 10))
        choose_button_old = wx.Button(panel, label="フォルダの選択", pos=(350, 25))

        # 最新プロジェクトファイル選択ボタン
        wx.StaticText(panel, wx.ID_ANY, label="最新プロジェクト", pos=(10, 60))
        choose_button_latest = wx.Button(panel, label="フォルダの選択", pos=(350, 75))
```

`wx.StaticText`←文字通り、すたてぃっくなテキストです。親はPanelです。
`pos=(横,縦)`でいい感じの位置に配置してます。

`wx.Button`がボタンです。こちらの親もPanelです。
後で使うので変数に代入しています。


###イベントハンドラ呼び出し

Bindメソッドは[【ここ】](https://maku77.github.io/python/wxpython/event-handler.html)に助けてもらいました。

```python
 self.old = wx.TextCtrl(panel, wx.ID_ANY, pos=(10, 30), size=(320, 20))
 choose_button_old.Bind(wx.EVT_BUTTON, self.choose_folder_old)

 self.latest = wx.TextCtrl(panel, wx.ID_ANY, pos=(10, 80), size=(320, 20))
 choose_button_latest.Bind(wx.EVT_BUTTON, self.choose_folder_latest)

 def choose_folder_old(self, event):
        """ フォルダの選択ボタンを押すと呼ばれるイベント。フォルダ選択ダイアログを開き、choose_textに反映 """

        folder = wx.DirDialog(self, style=wx.DD_CHANGE_DIR,
                              message="保存先フォルダ")

        if folder.ShowModal() == wx.ID_OK:
            folder_path = folder.GetPath()
        folder.Destroy()
        self.old.SetLabel(folder_path)

    def choose_folder_latest(self, event):
        """ フォルダの選択ボタンを押すと呼ばれるイベント。フォルダ選択ダイアログを開き、choose_textに反映 """

        folder = wx.DirDialog(self, style=wx.DD_CHANGE_DIR,
                              message="保存先フォルダ")

        if folder.ShowModal() == wx.ID_OK:
            folder_path = folder.GetPath()
        folder.Destroy()
        self.latest.SetLabel(folder_path)
```
ボタンを押したらダイアログが出てきて任意のフォルダを押すと
テキストボックスの中にパスが表示されます。
`wx.TextCtrl`がテキストボックスを作るクラスで
テキストボックスにはこちらから入力もできます。

Bindメソッドで**ボタンを押す**というイベント(`wx.EVT_BUTTON`)に
`choose_folder_old`、`choose_folder_latest`という自分で定義したメソッドを
イベントハンドラとして呼び出しています。

似たような処理(ほぼ完全一致)のメソッドを二つ定義しているので、
渡した引数に応じて処理を変えれるようにしたかったのですが、
上手くいきませんでした。

やり方わかる方教えて下さい。


##最終的なコード

```python

import wx

class Main(wx.Frame):

    def __init__(self, parent, id, title):
       
        wx.Frame.__init__(self, parent, id, title, size=(500, 300))
        panel = wx.Panel(self, id=wx.ID_ANY)

        # 旧プロジェクトファイル選択ボタン
        wx.StaticText(panel, wx.ID_ANY, label="旧プロジェクト", pos=(10, 10))
        self.old = wx.TextCtrl(panel, wx.ID_ANY, pos=(10, 30), size=(320, 20))
        choose_button_old = wx.Button(panel, label="フォルダの選択", pos=(350, 25))
        choose_button_old.Bind(wx.EVT_BUTTON, self.choose_folder_old)

        # 最新プロジェクトファイル選択ボタン
        wx.StaticText(panel, wx.ID_ANY, label="最新プロジェクト", pos=(10, 60))
        self.latest = wx.TextCtrl(panel, wx.ID_ANY, pos=(10, 80), size=(320, 20))
        choose_button_latest = wx.Button(panel, label="フォルダの選択", pos=(350, 75))
        choose_button_latest.Bind(wx.EVT_BUTTON, self.choose_folder_latest)


        # 画面を表示
        self.Show(True)
        # 画面の表示位置を中央に
        self.Centre()

    def choose_folder_old(self, event):
        """ フォルダの選択ボタンを押すと呼ばれるイベント。フォルダ選択ダイアログを開き、choose_textに反映 """

        folder = wx.DirDialog(self, style=wx.DD_CHANGE_DIR,
                              message="保存先フォルダ")

        if folder.ShowModal() == wx.ID_OK:
            folder_path = folder.GetPath()
        folder.Destroy()
        self.old.SetLabel(folder_path)

    def choose_folder_latest(self, event):
        """ フォルダの選択ボタンを押すと呼ばれるイベント。フォルダ選択ダイアログを開き、choose_textに反映 """

        folder = wx.DirDialog(self, style=wx.DD_CHANGE_DIR,
                              message="保存先フォルダ")

        if folder.ShowModal() == wx.ID_OK:
            folder_path = folder.GetPath()
        folder.Destroy()
        self.latest.SetLabel(folder_path)
  

def main():
    app = wx.App(False)
    Main(None, wx.ID_ANY, "Project Updater")
    app.MainLoop()


if __name__ == "__main__":
    main()
```

こんな感じです。
![projectUpdate.png](https://qiita-image-store.s3.amazonaws.com/0/244071/5d85e6d2-0d74-f5ee-318b-915472e3007a.png)

パス比較して、一致しないサブディレクトリだけのリスト作って
うんぬんかんぬんすればいけるんじゃないかと思ってます。

もしそれでいけたら忘れないうちにまた書きます。

まだまだ粗削りですが続き書きました→[こちら](https://qiita.com/OKsaiyowa/items/3a1bfc6e885e264cf200)