はじめに
Tkinterでタブ付きウィンドウを使った簡単なアプリを作ります。前回の「TkinterのTextで簡単GUIアプリ」で作った「エデイタ」風アプリにタブ付きウィンドウを導入し複数ファイルの編集を可能にします。タブ付きウィンドウを作るときはtkinter.ttkモジュールのNotebookウィジェットを使います。
完成イメージ
解説
インポート
tkinterとtkinter.ttkをインポートします。
import tkinter as tk
import tkinter.ttk as ttk
Notebookの作成
Notebookを作成してアプリのウィンドウに配置します。
root = tk.Tk()
notebook = ttk.Notebook(root)
notebook.pack(fill='both',expand=1)
タブの追加
タブに配置するフレームを作成し、Notebook.add()でタブを追加します。このままだと追加されたタブが裏に隠れているのでNotebook.select()で前面にします。Notebook.tabs()はtab_idリストを返しNotebook.index('end')がタブ数を返すので、タブ数を-1してリスト最後のtab_idをNotebook.select()に渡します。
frame=tk.Frame(notebook)
notebook.add(frame,text='title')
notebook.select(notebook.tabs()[notebook.index('end')-1])
選択されたタブ
引数のないNotebook.select()で選択されたタブのtab_idを返します。Notebook.tabs()が返したtab_idリストのindex()メソッドに選択されたtab_idを引数にして何個目に追加されたタブかを調べることができます。
idx=notebook.tabs().index(notebook.select())
全ソースコード
import os
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
class SbTextFrame(tk.Frame):
def __init__(self,master):
super().__init__(master)
text = tk.Text(self,wrap='none',undo=True)
x_sb = tk.Scrollbar(self,orient='horizontal')
y_sb = tk.Scrollbar(self,orient='vertical')
x_sb.config(command=text.xview)
y_sb.config(command=text.yview)
text.config(xscrollcommand=x_sb.set,yscrollcommand=y_sb.set)
text.grid(column=0,row=0,sticky='nsew')
x_sb.grid(column=0,row=1,sticky='ew')
y_sb.grid(column=1,row=0,sticky='ns')
self.columnconfigure(0,weight=1)
self.rowconfigure(0,weight=1)
self.text = text
self.x_sb = x_sb
self.y_sb = y_sb
def add_tab(fname):
global tframes,fnames,notebook
tframe=SbTextFrame(notebook)
tframes.append(tframe)
if os.path.isfile(fname):
f=open(fname,'r')
lines=f.readlines()
f.close()
for line in lines:
tframe.text.insert('end',line)
fnames.append(fname)
title=os.path.basename(fname)
notebook.add(tframe,text=title)
notebook.select(notebook.tabs()[notebook.index('end')-1])
def fileopen():
fname = filedialog.askopenfilename()
add_tab(fname)
def filesave():
global tframes,fnames,notebook
idx = notebook.tabs().index(notebook.select())
fname = fnames[idx]
tframe = tframes[idx]
f = open(fname,'w')
f.writelines(tframe.text.get('1.0','end-1c'))
f.close()
def main():
global root,notebook,tframes,fnames
root = tk.Tk()
root.title('tabbed editor')
root.geometry('400x300')
notebook = ttk.Notebook(root)
notebook.pack(fill='both',expand=1)
tframes = []
fnames = []
add_tab('new')
menubar = tk.Menu(root)
filemenu = tk.Menu(menubar,tearoff=0)
filemenu.add_command(label='Open',command=fileopen)
filemenu.add_command(label='Save',command=filesave)
filemenu.add_command(label='Exit',command=exit)
menubar.add_cascade(label='File',menu=filemenu)
root.config(menu=menubar)
root.mainloop()
if __name__ == '__main__':
main()
おわりに
今回はタブ付きウィンドウを使った「エディタ」風アプリを作りました。「エディタ」に限らず複数のウィンドウを使うときはタブを使うと画面がすっきりしていいですよね。