pythonでのGUI作成 tkinter使用して その1

## 概要

pythonで作ったツールを実行する際、自分で作ったものであればコマンドラインから呼び出すことでも問題はないのですが、開発に関係していない方が使うツールの場合画面から操作できた方が都合がよかったりします。pythonでアプリが作れないかいろいろ調べて作った内容をまとめてみました。まだ作りこみが甘いので徐々に調整していく予定です。

## 必要なもの

* python 3.7.2
* pandas
* numpy

## 公開場所

githubで公開しています。
https://github.com/snowpff14/etcresource/tree/master/pythonGui

## 処理内容

以前作ったseleniumの練習サイト操作用のスクリプト[こちら参照](https://qiita.com/snowp/items/9f51fd0d4b5b20196872)、エクセルファイルの列追加、行削除のスクリプト[こちら参照](https://qiita.com/snowp/items/94f8bb06a08e42af6bba)を起動できるようにしました。

* 画面上で可変のテキスト領域(ボタンの表示名やラベルなども含む)を使うときは以下のように`StringVar()`を使います。

```python

    inputFolder=StringVar()
    outputFolder=StringVar()

```
* 以下はファイルダイアログを開いて選択したファイルパスをテキストボックスに格納します。

```python
    def openFile(self):
        fTyp = [('','*.xlsx')]
        iDir = os.path.abspath(os.path.dirname(__file__))
        filename = filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir)
        return filename

    def fileButton(self):
       filename= self.openFile()
       self.inputFileName.set(filename)
```

* 以下は実際の処理を動かすところです。処理が終わるまで画面の方が固まってしまうので、threadを使ってます。ボタンに定義するのは`doExecute`となります。

```python

    def doExecute(self):
        # threading.Lock
        thread=threading.Thread(target=self.execute)
        thread.start()

    def execute(self):

        excelFile=pd.ExcelFile(self.inputFileName.get())
        reserveSheetTemp=excelFile.parse(sheet_name='予約シート',dtype='str',header=1)
        print(reserveSheetTemp.head())
        log=LoggerObj()
        driver=webdriver.Chrome('C:/webdrivers/chromedriver.exe')
        driver.get('http://example.selenium.jp/reserveApp/')

        reserveSheet=reserveSheetTemp.query('無効フラグ != "1"')
        testSideOrder=TestSiteOrder(driver,log,'test')
        # 勤務時間入力
        testSideOrder.inputOrder(reserveSheet)

        testSideOrder.createOkDialog('処理完了','登録処理完了')

```

* 以下のように`tkinter.TK()`を使って画面の定義を作っていきます。
    * titleでウィンドウのタイトルを設定
    * Frameで画面のサイズなどを定義します。

```python
root= tkinter.Tk()

    def main(self):
        root.title("Python GUI")
        content = ttk.Frame(root)
        frame = ttk.Frame(content,  relief="sunken", width=400, height=500)
```

* 以下のようにgridを使って画面にラベル、ボタンなどの部品を配置します。(一部抜粋しています)
    * gridを使うことで縦、横どこの位置に配置するかを調整することが可能です。
    * 可変する項目は`textvariable`を使って`StringVar`で宣言したものを指定すると項目の変更を反映させることができます。
    * `command`で起動する関数を設定します。
    * 最後に`mainloop()`を呼び出すことで画面を表示させ続けることができます。

```python
        content.grid(column=0, row=0)

        title.grid(column=0, row=0, columnspan=4)

        fileLabel=ttk.Label(content,text="予約情報")
        resultFolderLabel=ttk.Label(content,text="フォルダ指定")

        fileInput=ttk.Entry(content,textvariable=self.inputFileName,width=70)
        resultFolderInput=ttk.Entry(content,textvariable=self.outputFolder,width=70)

        self.progressMsgBox=ttk.Label(content,textvariable=self.progressMsg,width=70)

        self.progressBar=ttk.Progressbar(content,orient=HORIZONTAL,length=140,mode='indeterminate')
        self.progressBar.configure(maximum=10,value=0)

        fileInputButton=ttk.Button(content, text=BUTTON_LABEL_REFERENCE,command=self.fileButton)
        resultDirectoryInputButton=ttk.Button(content, text=BUTTON_LABEL_REFERENCE,command=self.inputResultFolderButton)
         
        executeButton=ttk.Button(content,text='実行',command=self.doExecute)
        fileExecuteButton1=ttk.Button(content,text='ファイル操作 挿入実行',command=self.fileInsert)
        fileExecuteButton2=ttk.Button(content,text='ファイル操作 デリート実行',command=self.fileDelete)
        root.mainloop()
```

起動すると以下のような画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108811/1648fe66-a8e8-3d46-0f4b-adb39a8804e2.png)

とりあえず今回はこのくらいで
[続き作成しました](https://qiita.com/snowp/items/fff785023ef4c7807af5)