Python初心者がブログの検索順位取得ツールを作っています。
前回は、画面案を作り、とりあえずtkinterでファイル選択ボタンを実装してみました。
今回は、作りたい画面の中心的機能である検索キーワード等を表形式に表示する部分を作ってみます。
作りたい画面は下の通りです。
表は複数の列からなり、チェックボックスを埋め込みたい。
さらにスクロールバーを付けたい。
この要望がなかなか大変なことになりました。
tkinterでチェックボックスを埋め込んだ複数列の表を作り、スクロールバーを付ける方法は、簡単には見つかりませんでしたので、いろいろ組み合わせて自分で実装してみました。
チェックボックス入りの表とスクロールバーを表示するコード
今回はtkinterを使って検索キーワードや順位を表形式で表示する部分を作っていきます。
やったことは
- grid機能でLabelとチェックボックスを配置
- 背景色をつける
- スクロールバー用にFrameとCanvasを設定
です。
表形式に表示する方法は、ListBoxやTreeviewがあります。
しかし、ListBoxは複数列ができない、Treeviewは複数列はできるけど、チェックボックスを埋め込めないので、諦めました。
(※あくまでも、調べた範囲でやり方が分からなかった)
Labelとチェックボックス(checkbutton)をgridで並べることで表のように表示させることにしました。
また、表をスクロールできるようにしたかったため、CanvasやFrameといったwidgetを使用しています。
参考ページ
表のようにLabelを配置する方法⇒How to delete entire row in Tkinter grid layout
スクロールバーの設定方法⇒Tkinterでスクロールできるようにしたい
余談ですが、上記参考ページである「stackoverflow」はプログラミングの難しい課題も解決できちゃうので、めっちゃ参考になります。
ありがたいです。
では、今回作成部分のソースコードです。
表示するデータは、今回は埋め込みでリストを作りました。
今後ファイル読み込みでリストを取得する予定。
import tkinter
import tkinter.ttk
root = tkinter.Tk()
root.title('ブログ検索順位取得ツール') #タイトル
root.geometry('500x200') #サイズ
#表用のリスト(あとでExcel読み込みに対応させる)
list_keyword = ['理系夫婦','BabyKumon 効果','Python GIF','fortran 配列','python google','BabyKumon 絵本','VBA 入門 ユーザーフォーム']
list_rank = [4,5,8,7,10,12,35]
list_title = ['xxxxxx','yyyyyy','zzzzzz','ssss','dddd','ffff','gggg']
num_list = len(list_keyword) #リストの数
#Canvas widgetを生成
canvas = tkinter.Canvas(root,width=480,height=150,bg='white') #背景を白に
canvas.grid(row=1,rowspan=num_list,column=0,columnspan=5) #7行x5列分
#スクロールバー
vbar=tkinter.ttk.Scrollbar(root,orient=tkinter.VERTICAL) #縦方向
vbar.grid(row=1,rowspan=7,column=5,sticky='ns') #7行分の長さで設置
#スクロールバーの制御をCanvasに通知する処理
vbar.config(command=canvas.yview)
#Canvasの可動域をスクロールバーに通知する処理
canvas.config(yscrollcommand=vbar.set)
#スクロール可動域<=これがないと、どこまでもスクロールされてしまう。
sc_hgt=int(150/6*(num_list+1)) #スクロールの縦の範囲 リストの数+ヘッダー分に
canvas.config(scrollregion=(0,0,500,sc_hgt))
#Frameを作成
frame = tkinter.Frame(canvas,bg='white') #背景を白に
#frameをcanvasに配置
canvas.create_window((0,0),window=frame,anchor=tkinter.NW,width=canvas.cget('width')) #anchor<=NWで左上に寄せる
#header row=1に設定する文字列 余白は0に
e0=tkinter.Label(frame,width=5,text='select',background='white')
e0.grid(row=1,column=0,padx=0,pady=0,ipadx=0,ipady=0) #0列目
e1=tkinter.Label(frame,width=25,text='keyword',background='white')
e1.grid(row=1,column=1,padx=0,pady=0,ipadx=0,ipady=0) #1列目
e2=tkinter.Label(frame,width=5,text='rank',background='white')
e2.grid(row=1,column=2,padx=0,pady=0,ipadx=0,ipady=0) #2列目
e3=tkinter.Label(frame,width=30,text='title',background='white')
e3.grid(row=1,column=3,padx=0,pady=0,ipadx=0,ipady=0) #3列目
irow = 2
irow0=2
erow=num_list+irow0
while irow < erow: #リストの数分ループしてLabelとチェックボックスを設置
#色の設定
if irow%2==0:
color='#cdfff7' #薄い青
else:
color='white'
#チェックボックスの設置
bln=tkinter.BooleanVar()
bln.set(False) #チェックボックスの初期値
c = tkinter.Checkbutton(frame,variable = bln,width=5,text='',background='white')
c.grid(row=irow,column=0,padx=0,pady=0,ipadx=0,ipady=0) #0列目
#検索キーワード
a1=list_keyword[irow-irow0]
b1=tkinter.Label(frame,width=25,text=a1,background=color)
b1.grid(row=irow,column=1,padx=0,pady=0,ipadx=0,ipady=0) #1列目
#検索順位
a2=list_rank[irow-irow0]
b2=tkinter.Label(frame,width=5,text=a2,background=color)
b2.grid(row=irow,column=2,padx=0,pady=0,ipadx=0,ipady=0) #2列目
#記事タイトル
a3=list_title[irow-irow0]
b3=tkinter.Label(frame,width=30,text=a3,background=color)
b3.grid(row=irow,column=3,padx=0,pady=0,ipadx=0,ipady=0) #3列目
irow=irow+1
#ウィンドウを動かす
root.mainloop()
コードの注意点
上記コード、長いので個別の説明は省きます(というか、理解不足でできない)。
今回のキモでもあり、少々躓いたgrid機能のみ紹介します。
Labelでもチェックボックスでも、画面上のどこに配置するかは「grid」で設定します。
object.grid(row=0,column=0)
といったように、行(row)と列(column)で指定します。番号は0始まりです。
今回、row=0にファイル選択ボタンを配置し、row=1に表のヘッダーを、row=2以降に表の中身を配置しています。
column=0がチェックボックス、column=1が検索キーワード、column=2が検索順位、column=3が記事タイトルです。
スクロールバーは、
vbar.grid(row=1,rowspan=7,column=5,sticky=’ns’)
と、row=1から7行にわたって設置。列はcolumn=5としています。なぜかcolumn=4だと上手くいきませんでした(謎)。
「sticky」オプションで”ns”(上下に引き延ばす)を指定しています。
また、Labelとチェックボックスでは余白の指定もしています。
これは背景の色の塗り具合を調整するためです。
padxが外側の横の余白
padyが外側の縦の余白
ipadxが内側の横の余白
ipadyが内側の縦の余白
です。すべて0にしました。
実行結果
上記のソースコードを実行してみます。
なんとかそれっぽい表が表示されました。
スクロールバーも機能しています。
ここまで表示できるようになるのに、かなり時間がかかりました。
はっきり言って、難しい。(VBAやC#のが楽)
今後の課題
●マウス対応
スクロールバーを設置したものの、マウスホイールを動かした場合にスクロールできません。
そういう機能は別でバインドさせないといけないようです。
マウスで動いた方がユーザー的には楽なので、こちらは対応する予定。
●表の大きさを可変にしたい
現状は表の幅(canvas,frame,label)が固定になっていて、画面のサイズをドラッグで変えた場合に対応できていません。
画面の大きさに合わせて表の幅も変えられるようにしたいです。
今回作った部分についての課題はとりあえず2つです。
あとは他のボタン機能を実装しないと。
なかなか大変になってきました。
いつ完成するのでしょう・・・
んじゃ、また~
おススメのプログラミング独学方法はこちらの記事にまとめました!
コメント