7ページ目です。
今回は、JSONファイルを読み込んで、カテゴリーのリストをコンボボックスに追加し、カテゴリーを選ぶと該当する名称とURLをそれぞれリストボックスで表示するようにします。
今回使用する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を削除する処理も必要ですよね。
次回はそのあたりのカスタマイズをやってみましょう!
では今回はこの辺で終わりにします。
次回をお楽しみに。
コメント