【python】作りながら覚えるデスクトップアプリ開発|tkinter

python

7ページ目です。

今回は、JSONファイルを読み込んで、カテゴリーのリストをコンボボックスに追加し、カテゴリーを選ぶと該当する名称とURLをそれぞれリストボックスで表示するようにします。

  1. python×tkinterでGUI作成
    1. python の開発環境は Anaconda がおすすめ
    2. ウィンドウの各種設定項目を追加
  2. tkinterのボタンクリックでリンク開く方法
  3. ここまでの全コード
  4. 【python】tkinter基礎⇒応用編
    1. URLをクリックするとリンクを開くようにカスタマイズ
    2. リンクを開く処理の実装
  5. 今回カスタマイズした結果の全コード
  6. 複数ページのリンクを表示する
    1. forループでページ数の連番を追加する処理
    2. リストにしたURLをlistboxで表示してみよう!
    3. submit 関数のカスタマイズ
  7. 今回のカスタマイズした全コード
  8. 設定ファイル(*.ini)の処理をコーディング
    1. 設定ファイルの保存フォルダを作成
    2. 保存フォルダに設定ファイル(*.ini)を保存
    3. 設定ファイル(*.ini)を扱うモジュール
  9. これまでのコードに設定ファイル(*.ini)の処理を組み込む
  10. JSONファイルで、お気に入りサイトのURLを管理
    1. サブアプリの画面をカスタマイズ
    2. 辞書型(ディクショナリー型)
  11. JSONファイルにデータを追加するツールを作成
  12. JSON書き込み処理の実装
    1. コードの解説
    2. URLの正規表現によるチェック
    3. URLの存在チェック
  13. 動作確認
  14. 今回使用するJSONファイル
  15. コンボボックスとリストボックスの追加
    1. コンボボックスにカテゴリーを追加する関数
    2. URLをブラウザで開く処理
  16. 今回の全コード
    1. 動作確認
  17. カテゴリーやURLの追加や削除の関数
    1. add_category 関数の説明
    2. remove_category関数の説明
    3. remove_url関数の説明
  18. 関数を操作する例
  19. ここからは・・・
  20. まとめ

今回使用するJSONファイル

今回は、カテゴリー分けしたJSONファイルを用意します。

{
    "blog": {
        "p1": "https://bliss-growth.com/python_tkinter/",
        "p2": "https://bliss-growth.com/python_tkinter/2/",
        "p3": "https://bliss-growth.com/python_tkinter/3/",
        "p4": "https://bliss-growth.com/python_tkinter/4/"
    },
    "site": {
        "google": "https://www.google.com/",
        "yahoo": "https://www.yahoo.co.jp/",
        "amazon": "https://www.amazon.co.jp/",
        "rakuten": "https://item.rakuten.co.jp/"
    },
    "Photo": {
        "pixabay": "https://pixabay.com/ja/",
        "unsplash": "https://unsplash.com/ja",
        "500px": "https://500px.com/",
        "o-dan": "https://o-dan.net/ja/"
    },
    "illust": {
        "undraw": "https://undraw.co/illustrations",
        "enpitsu-sozai": "https://enpitsu-sozai.com/",
        "vectorshelf": "https://vectorshelf.com/",
        "irasutoya": "https://www.irasutoya.com/",
        "irasuton": "http://www.irasuton.com/"
    }
}

例えば副業をされている方は、案件ごとにカテゴリー分けして管理するということもできますね。

コンボボックスとリストボックスの追加

コンボボックスを使うには、tkinter.ttk をインポートする必要があります。

import tkinter.ttk as ttk

また、ListBox の制御用に tkinter から END をインポートする必要があります。

from tkinter import END

以下がコンボボックスと2つのリストボックスを表示させるコードです。

v = tk.StringVar()
combobox = ttk.Combobox(list_frame,textvariable= v, height=5,values=get_category(), style="office.TCombobox")
combobox.pack(side = tk.TOP)
combobox.bind('<<ComboboxSelected>>', select_combo)
combobox.set('カテゴリーを選択') #初期表示

listbox_name = tk.Listbox(list_frame,borderwidth=3,selectmode='SINGLE',width=10,height=8)
listbox_name.pack(side = tk.LEFT)

listbox_site = tk.Listbox(list_frame,borderwidth=3,selectmode='SINGLE',width=50,height=8)
listbox_site.pack(side = tk.LEFT)
listbox_site.bind("<Double-Button-1>", listbox_event)
listbox_site.bind("<Key-Return>", listbox_event)

コンボボックスにカテゴリーを追加する関数

先ほどのコードで、combobox.bind('<<ComboboxSelected>>', select_combo) が、コンボのカテゴリーを選択した際にイベントが発生し、関数を呼ぶ部分で、以下の select_combo 関数が呼ばれます。

def select_combo(event):
    category = combobox.get()
    print(category)
    data = read_json()  #JSONを辞書へ
    listbox_name.delete(0,END)
    listbox_site.delete(0,END)
    name_list = []
    url_list = []
    for name,url in data[category].items():
        listbox_name.insert(END,name)
        listbox_site.insert(END,url)

処理としては、カテゴリーを選ぶと、そのカテゴリーの名称とURLがリスト表示されるというものです。

URLをブラウザで開く処理

右側のURLリストをダブルクリックか行選択された状態でEnter押下すると、選択されたURLがブラウザの新規タブで開かれます。

def ListBox_LeftDoubClick(event):
    target = listbox_site.get(listbox_site.curselection())
    print(target)
    webbrowser.open_new(target)

listbox_site.bind("<Double-Button-1>", ListBox_LeftDoubClick)
listbox_site.bind("<Key-Return>", ListBox_LeftDoubClick)

これもバインドでイベントを発生させていますね。

今回の全コード

ずいぶん長いコードになってしまいました。

import tkinter as tk
import tkinter.ttk as ttk
from tkinter import END
import webbrowser
import subprocess
import os
import json
from tkinter import messagebox
import re

#色の設定
bg_color1='cornsilk2'
bg_color2='LightSteelBlue1'
bg_color3='#A8BAC3'
bg_color4='#C9AC85'

# ウィンドウの作成
root = tk.Tk()
root.title('python×tkinter')
root.geometry('380x360')
root.resizable(1, 1)
root.config(bg=bg_color3)
root.attributes("-topmost", True)  #常に前面に表示

# frameの作成
frame1 = tk.Frame(root,bg=bg_color2)
list_frame = tk.Frame(root,bg=bg_color1)
frame2 = tk.Frame(root,bg=bg_color4)

frame1.pack(fill=tk.BOTH, expand=True)
list_frame.pack(fill=tk.BOTH, expand=True)
frame2.pack(fill=tk.BOTH, expand=True)

#jsonファイルのパス
json_dir= os.path.join(os.getcwd(),'json')
json_path = os.path.join(json_dir,'sitelist.json')

#正規表現でURLのパターンチェック
pattern = "https?://[\w/:%#\$&\?\(\)~\.=\+\-]+"
    
#関数の作成
def open_json_dir():
    subprocess.Popen(['explorer',json_dir])
    
def read_json():
    #jsonの読み込み
    with open(json_path) as f:
        json_load = json.load(f)
    return json_load
    
def add_dict(data,key,val):
    site_dict = data[combobox.get()]
    site_dict[key]=val  #keyとvalを辞書に追加
    return data

def write_json():
    key = txt_name.get()  #入力値:サイト名
    val = txt_url.get()  #入力値:URL

    if len(key) == 0:    
        # メッセージボックス(警告) 
        messagebox.showwarning('サイト名の確認','サイト名の入力が正しくありません。')
    elif not re.match(pattern, val): #urlか?
        # メッセージボックス(警告) 
        messagebox.showwarning('URLの確認','URLの入力が正しくありません。') 
    elif combobox.get() == "":
        messagebox.showwarning('カテゴリーの確認','カテゴリーが選ばれていません。') 
    else:
        dict_data = read_json()  #JSONを辞書へ
        add_data = add_dict(dict_data,key,val)
        #jsonの書き込み
        with open(json_path, 'w') as f:
            json.dump(add_data, f, indent=4)
        messagebox.showinfo('データ保存','JSONファイルに保存しました。')
        #0文字目~最後まで入力値を削除
        txt_name.delete(0, tk.END)
        txt_url.delete(0, tk.END)

def get_category():
    data = read_json()  #JSONを辞書へ
    c_list=[]
    for category, links in data.items():
        print(f"Category: {category}")
        c_list.append(category)
    return c_list
        
def select_combo(event):
    category = combobox.get()
    print(category)
    data = read_json()  #JSONを辞書へ
    listbox_name.delete(0,END)
    listbox_site.delete(0,END)
    name_list = []
    url_list = []
    for name,url in data[category].items():
        listbox_name.insert(END,name)
        listbox_site.insert(END,url)

def listbox_event(event):
    target = listbox_site.get(listbox_site.curselection())
    print(target)
    webbrowser.open_new(target)
    
#ウィジェットの作成
lbl01 = tk.Label(frame1,text='python_tkinter JSONに追加',bg=bg_color2)
lbl01.pack()

v = tk.StringVar()
val = get_category()

combobox = ttk.Combobox(list_frame,textvariable= v, height=5,values=val, style="office.TCombobox")
combobox.pack(side = tk.TOP)
combobox.bind('<<ComboboxSelected>>', select_combo)
combobox.set('カテゴリーを選択')

listbox_name = tk.Listbox(list_frame,borderwidth=3,selectmode='SINGLE',width=10,height=8)
listbox_name.pack(side = tk.LEFT)

listbox_site = tk.Listbox(list_frame,borderwidth=3,selectmode='SINGLE',width=50,height=8)
listbox_site.pack(side = tk.LEFT)
listbox_site.bind("<Double-Button-1>", listbox_event)
listbox_site.bind("<Key-Return>", listbox_event)

lbl02 = tk.Label(frame1,text='カテゴリーを選びサイト名とURLを入力してください',bg=bg_color2)
lbl02.pack()
lbl_name = tk.Label(frame2,text='サイト名:',bg=bg_color4)
lbl_name.grid(row=0, column=0, padx=5, pady=5)
txt_name = tk.Entry(frame2,width=28)
txt_name.grid(row=0, column=1, padx=5, pady=5)
lbl_url = tk.Label(frame2,text='URL:',bg=bg_color4)
lbl_url.grid(row=1, column=0, padx=5, pady=5)
txt_url = tk.Entry(frame2,width=28)
txt_url.grid(row=1, column=1, padx=5, pady=5)

#ボタンの作成
btn_ini_write = tk.Button(root,text='保存',command=write_json)
btn_ini_write.pack()

button = tk.Button(root,text='JSONフォルダを開く',command=open_json_dir)
button.pack(expand = True)

# ウィンドウのループ処理
root.mainloop()

コードを実行して、カテゴリーで「blog」を選択するとこのようになります。

動作確認

JSONファイルのこのブログのURLですが、P4までになっているので、動作確認として7ページ目まで追加してみましょう。

{
    "blog": {
        "p1": "https://bliss-growth.com/python_tkinter/",
        "p2": "https://bliss-growth.com/python_tkinter/2/",
        "p3": "https://bliss-growth.com/python_tkinter/3/",
        "p4": "https://bliss-growth.com/python_tkinter/4/"
以下省略・・・

コンボボックスで「blog」を選んで

「p5」「https://bliss-growth.com/python_tkinter/5/"」
「p6」「https://bliss-growth.com/python_tkinter/6/"」
「p7」「https://bliss-growth.com/python_tkinter/7/"」

と3項目を追加してみてください。

他のカテゴリーでもいろいろと追加してみるとよいですね。

ところで、新たにカテゴリーを追加したり、カテゴリーやURLを削除する処理も必要ですよね。

次回はそのあたりのカスタマイズをやってみましょう!

では今回はこの辺で終わりにします。

次回をお楽しみに。

コメント

タイトルとURLをコピーしました