PythonでPoketの代わりになるGUIアプリを作ってみた

**Python**と**Tkinter**、**SQlite3**を使って、**Poket**の代わりになる**GUIアプリ**を作成してみました。

## アプリの目的

**気になる記事やサイトを、より気軽に保存できるようにする。**

今見ているページを保存してあとで読めるWebサービス「**Poket**」( https://getpocket.com/ )は便利なのですが、気軽にどんどん保存すると、後で探しづらくなってしまいます。

また、Poketサービスを主に仕事用として使っているため、趣味など他のことは保存するのをためらってしまうことが多々ありました。

さらに、Poketがローカル環境で使えると便利なのではないかと考え、アプリの制作に踏み切りました。

## アプリの機能

アプリのコードを実行することで、GUIアプリが自動で起動します。

### INPUT

アプリを起動させて、「SITE NAME」、「URL」を書き込み、INPUTボタンを押すことで、データベース(site-url.db)内のテーブル(poket)に「サイト名」とその「URL」がセットで保存されます。

### VIEW

データベース(site-url.db)内のテーブル(poket)に保存されたデータがターミナル上で一覧表示されます。

表示されたURLにアクセスしたい場合は、**Ctrボタンを押しながらクリック**します。クリックすると、Webページが自動で開きます。

### DELETE

入力ダイアログの「SITE NAME」にサイト名を書き込み、DELETEボタンを押すと、データが削除されます。


### CLEAR

CLEARボタンを押すことで、一度 入力ダイアログに入力した内容を消去できます。複数のサイト/URLを連続で保存したり、削除したりするときに使います。



## 用意するもの

### DBファイル

アプリを利用するには以下のものが必要になります。

データベースファイル**site-url.db**を作成し、ホームディレクトリに保存します。

※データベースを作ったことがない人は、こちらのGUIアプリで作成してください。

**SQlite3のDB作成、閲覧、CSVインポート、出力できるGUIアプリを作成してみた！** - Qiita https://qiita.com/akiba_burari/items/bbcf9a7837099a476507

### テーブルのデータ

サイト名とURLを保存するためのテーブル「**poket**」を作成します。

カラムはテキスト形式で「**field1**」「**field2**」としています。

### pandas インストール

pandasをインストールしておきます。

```
pip install pandas
```


## アプリのコード

```python:poket-app.py
# coding: utf-8

#import で tkinter を読み込み as を使って tk と省略
import tkinter as tk

#pandasをインポート
import pandas as pd

#データベースをインポート
import sqlite3

#データベースに接続する
conn = sqlite3.connect('site-url.db')
c = conn.cursor()

#root = tk.TK( ) でウィンドウを作成
root= tk.Tk()

#ウィンドウのサイズを設定
root.geometry("500x300") 

#ラベル1
label1 = tk.Label(root, text='SITE NAME', font=('Noto Sans CJK JP', 15))
label1.pack(side="top")

#テキストボックス（複数行）を生成
text_box1 = tk.Text()
text_box2 = tk.Text()

#テキストボックス1を配置
text_box1 = tk.Text(height=1) #行数でサイズを指定
text_box1.pack(padx=30,pady=2) 

#ラベル1
label1 = tk.Label(root, text='URL', font=('Noto Sans CJK JP', 15))
label1.pack(side="top")

#テキストボックス2を配置
text_box2 = tk.Text(height=1) #行数でサイズを指定
text_box2.pack(padx=30,pady=2) 


#ボタンを作成
button_1 = tk.Button(text="INPUT")
button_1.pack()

button_2 = tk.Button(text="VIEW")
button_2.pack()

button_3 = tk.Button(text="DELETE")
button_3.pack()

button_4 = tk.Button(text="CLEAR")
button_4.pack()




#関数でテキストボックスに入力された値を取得
def INPUT():
    
    input_text1 = text_box1.get( "0.0", "end").replace('\n','')
    
    input_text2 = text_box2.get( "0.0", "end").replace('\n','')

    #データの挿入
    sql="INSERT INTO poket VALUES (?, ?)"
    data= [(input_text1, input_text2)]
    conn.executemany(sql, data)
    
    print("Connected to Database Successfully")
    #保存（コミット）する
    conn.commit()
    print("Record added successfully")
    c.execute("SELECT * from poket")
    print(c.fetchall())

    #データベースへの接続を終了する
    #conn.close()
    

def VIEW():
    pd.DataFrame()
    df = pd.DataFrame()
    df = pd.read_sql("SELECT * FROM 'poket'", conn)
    print(df)
    

def DELETE():
    input_text1 = text_box1.get( "0.0", "end").replace('\n','')
    data = input_text1
    sql="""DELETE from poket where field1 = ?; """
    c.execute(sql, (data, ))
    
    print("Connected to Database Successfully")
    #保存（コミット）する
    conn.commit()
    print("Record deleted successfully ")
    c.execute("SELECT * from poket")

    print(c.fetchall())

    #データベースへの接続を終了する
    #conn.close()

def CLEAR():
    text_box1.delete("0.0", tk.END)
    text_box2.delete("0.0", tk.END)



#関数とボタンを押したときのアクションを関連付ける

button_1["command"] = INPUT

button_2["command"] = VIEW

button_3["command"] = DELETE

button_4["command"] = CLEAR

#button["command"] = create_window

# ボタンの位置を指定
button_1.place(x = 220, y = 100)
button_2.place(x = 220, y = 140)
button_3.place(x = 220, y = 180)
button_4.place(x = 220, y = 220)


#root.mainloop( ) で作成したウィンドウを表示
root.mainloop()

```





## 作成したアプリをexe化する

pyinstallerを使って、アプリをexe化することができます。exe化すると、ボタンをダブルクリックするだけでアプリを起動できるようになります。

```
pip install pyinstaller
```

```
pyinstaller poket-app.py
```

Linux Ubuntuだと非常に簡単にexe化できます。

Windowsはけっこう難しかったです。詳しい手順は以下の記事にまとめてあります。

**Python デスクトップアプリ開発に挑戦してみた！** https://zenn.dev/akibaburari/articles/32a89b19fcf889

## ＜補足1＞ TKinter SQlite3でレコードを追加する方法

以下の部分がポイントになります。

```python:
#データの挿入
    sql="INSERT INTO poket VALUES (?, ?)"
    data= [(input_text1, input_text2)]
    conn.executemany(sql, data)
```

## ＜補足2＞ TKinter SQlite3でレコードを削除する方法

以下の部分がポイントになります。

```python:

data = input_text1
    sql="""DELETE from poket where field1 = ?; """
    c.execute(sql, (data, ))

```

この書き方はネット上では掲載されていませんでした。ネット上では、カラムがIDになっているものが多く、「3」などの数字の消し方が多く掲載されています。その方法では、サイト名、例えば「朝日新聞」などのテキスト文字が消えないので、上記のように変更しました。

なお、入力ダイアログ(entry)のところで、

```
 input_text1 = text_box1.get( "0.0", "end").replace('\n','')
```

とreplaceを入れているのは、SQlite3の方に改行/nが追加されてしまうためです。これを消すために、replaceを入れています。

## ＜補足3＞ ブラウザの起動について

今回作成したアプリでは、ターミナル上に表示されたURLをCtrボタンを押しながらクリックすることで、任意のWebサイトにアクセスするようになっています。

最初は別ウィンドウを作り、そこにラベルでURLを一覧表示させようとしていましたが、これがかなり難しいです。一つのURLをWebページにジャンプさせることはできても、複数のURLをそれぞれのWebサイトへアクセスさせるとなると、とたんに複雑なコードになってしまいます。そこで今回はターミナル上からWebサイトへアクセスするようにしました。