はじめに
Tkinter の使い方に慣れるため、もう一つGUIアプリを作ってみた、テクニック的には以下のものを織り込んだ。
- タブを使う
- 表を使う
- matplotlib 経由で TeX 数式を canvas に描画
- 計算結果は messagebox に表示
参考にしたサイトは以下の通り。
(タブの使い方)
【Tkinter】【コピペ可】ボタン、タブ、表の使い方をざっくり説明
https://kazuwo-blog.com/python-tkinter/#index_id10
(matplotlibのcanvasへの埋め込み)
Embedding in Tk
https://matplotlib.org/3.1.0/gallery/user_interfaces/embedding_in_tk_sgskip.html
(matplotlibで余白の調整)
【python】matplotlibで図の余白を調整する
https://hayataka2049.hatenablog.jp/entry/2018/10/11/030103
(表の作成)
⑨ 表(テーブル)の作成【python tkinter sqlite3で家計簿を作る】
https://memopy.hatenadiary.jp/entry/2017/06/02/230723
動作中写真
2つのタブ(Concrete と Rock)のうち、Concrete での計算実行結果画面。
何に出力するか考えたが、このアプリでは計算結果の数値が確認できればいいので、messagebox に出力することとした。
タブの中に入力用の参考として小さな表を表示している。
使っている計算式を表示したもの。普通に matplotlib での描画コマンドを打ち、canvas に表示させているもの。これを表示すると、メイン画面の左上の x を押しても、画面は閉じるが Python が終了しない事態に見舞われたため、Quit により Python そのものを終了させるようにした。
2つのタブ(Concrete と Rock)のうち、Rock での計算実行結果画面。
ここでもタブの中に入力用の参考として小さな表を表示している。
matplotlib での描画後、messagebox に表示されるアイコンが変わってしまっている。icon='info' で明示してもアイコンが変化してしまう。本質に影響はないので未解決のまま。
コード
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
def end_q():
quit()
def plot():
fsz=11
xmin,xmax,dx=0, 5, 1
ymin,ymax,dy=0, 10, 1
fig = plt.figure(figsize = (3,3),dpi = 100)
plt.rcParams['font.size']=fsz
plt.rcParams['font.family']='sans-serif'
plt.subplots_adjust(left=0.1,right=0.95,bottom=0.1,top=0.95)
plt.xlim([xmin,xmax])
plt.ylim([ymin,ymax])
plt.axis('off')
ss=[]
ss.append(r'$\sigma_c$: compressive strength (positive)')
ss.append(r'$\sigma_t$: tensile strength (positive)')
ss.append(r'$\phi$: internal friction angle')
ss.append(r'$c$: cohesion')
ss.append('For Concrete')
ss.append(r'$\sigma_t=0.23\cdot (\sigma_c)^{2/3}$')
ss.append(r'$\phi=\sin^{-1}\left(\frac{\sigma_c-\sigma_t}{\sigma_c+\sigma_t}\right)$')
ss.append(r'$c=\frac{\sigma_c\cdot \sigma_t}{\cos\phi\cdot (\sigma_c+\sigma_t)}$')
ss.append('For Rock')
ss.append(r'$\sigma_c=\frac{2\cdot c\cdot \cos\phi}{1-\sin\phi}$')
ss.append(r'$\sigma_t=\frac{2\cdot c\cdot \cos\phi}{1+\sin\phi}$')
xy=np.array([
[0,9.5-0*0.6],
[0,9.5-1*0.6],
[0,9.5-2*0.6],
[0,9.5-3*0.6],
[0,6.5-0*1.0], # For Concrete
[1,6.5-1*1.0],
[1,6.5-2*1.0],
[1,6.5-3*1.0],
[0,6.5-4*1.0], # For Rock
[1,6.5-5*1.0],
[1,6.5-6*1.0]
])
for i in range(len(ss)):
plt.text(xy[i,0],xy[i,1],ss[i],ha='left',va='center',fontsize=fsz)
return fig
def show_eqs():
sub_win=tk.Toplevel()
sub_win.title('Equations')
fig=plot()
canvas = FigureCanvasTkAgg(fig,master=sub_win)
canvas.draw()
canvas.get_tk_widget().pack()
sub_win.mainloop()
def click_t1():
global entry_t1a
# Concrete
sigc=float(entry_t1a.get()) # compressive strength
sigt=0.23*sigc**(2/3) # tensile strength
sn=(sigc-sigt)/(sigc+sigt) # sin(phi)
cs=np.sqrt(1-sn**2) # cos(phi)
phi=np.degrees(np.arcsin(sn)) # internal friction angle
cc=(1+sn)/2/cs*sigt # cohesion
s0='Concrete'
s1='sigc (MPa)={0:6.3f}'.format(sigc)
s2='sigt (MPa)={0:6.3f}'.format(sigt)
s3='cc (MPa)={0:6.3f}'.format(cc)
s4='phi (deg)={0:6.3f}'.format(phi)
ss=s0+'\n'+s1+'\n'+s2+'\n'+s3+'\n'+s4
if messagebox.showinfo('Concrete',ss)=='ok': entry_t1a.focus_set()
def click_t2():
global entry_t2a,entry_t2b
# Rock
cc =float(entry_t2a.get()) # cohesion
phi=float(entry_t2b.get()) # internal friction angle
sigc=2*cc*np.cos(np.radians(phi))/(1-np.sin(np.radians(phi)))
sigt=2*cc*np.cos(np.radians(phi))/(1+np.sin(np.radians(phi)))
s0='Rock'
s1='cc (MPa)={0:6.3f}'.format(cc)
s2='phi (deg)={0:6.3f}'.format(phi)
s3='sigc (MPa)={0:6.3f}'.format(sigc)
s4='sigt (MPa)={0:6.3f}'.format(sigt)
ss=s0+'\n'+s1+'\n'+s2+'\n'+s3+'\n'+s4
if messagebox.showinfo('Rock',ss)=='ok': entry_t2a.focus_set()
def ini_t1():
global entry_t1a
entry_t1a.delete(0,tk.END)
entry_t1a.insert(tk.END,'25')
def ini_t2():
global entry_t2a,entry_t2b
entry_t2a.delete(0,tk.END)
entry_t2b.delete(0,tk.END)
entry_t2a.insert(tk.END,'3.506')
entry_t2b.insert(tk.END,'58.666')
def main():
global entry_t1a,entry_t2a,entry_t2b
root =tk.Tk()
root.title('Shear strength')
button_eqs=tk.Button(root,text='Show Equations',command=show_eqs)
button_eqs.pack()
nb = ttk.Notebook(root)
tab1 = tk.Frame(nb)
tab2 = tk.Frame(nb)
nb.add(tab1, text='Concrete')
nb.add(tab2, text='Rock')
nb.pack()
label_t1a=tk.Label(tab1,text='sigc (MPa)')
entry_t1a=tk.Entry(tab1,justify=tk.CENTER,width=7,bg='#000080')
button_t1a=tk.Button(tab1,text='Calculcation',command=click_t1)
button_t1b=tk.Button(tab1,text='(Initial value)',command=ini_t1)
label_t1a.grid(row=0,column=0)
entry_t1a.grid(row=0,column=1)
button_t1a.grid(row=1,column=0,columnspan=2)
button_t1b.grid(row=2,column=0,columnspan=2)
ini_t1() # initial value
label_t1c=tk.Label(tab1,text='sigc = cylinder strehgth')
label_t1c.grid(row=4,column=0,columnspan=2)
s1='Cube (MPa)'
s2='Cylinder (MPa)'
bs=np.array([15,20,25,30,35,40,45,50]) # BS
en=np.array([12,16,20,25,29,32,35,40]) # EN
tree = ttk.Treeview(tab1)
tree['columns']=(1,2)
tree['show']='headings'
tree['height']=len(bs)
tree.column(1,anchor='center',width=80)
tree.column(2,anchor='center',width=80)
tree.heading(1,text=s1,anchor='center')
tree.heading(2,text=s2,anchor='center')
for i in range(0,len(bs)):
tree.insert(parent='',index='end',values=(bs[i],en[i]))
tree.grid(row=5,column=0,columnspan=2)
label_t2a=tk.Label(tab2,text='cc (MPa)')
entry_t2a=tk.Entry(tab2,justify=tk.CENTER,width=7,bg='#000080')
label_t2b=tk.Label(tab2,text='phi (deg)')
entry_t2b=tk.Entry(tab2,justify=tk.CENTER,width=7,bg='#000080')
button_t2a=tk.Button(tab2,text='Calculation',command=click_t2)
button_t2b=tk.Button(tab2,text='(Initial value)',command=ini_t2)
label_t2a.grid(row=0,column=0)
entry_t2a.grid(row=0,column=1)
label_t2b.grid(row=1,column=0)
entry_t2b.grid(row=1,column=1)
button_t2a.grid(row=2,column=0,columnspan=2)
button_t2b.grid(row=3,column=0,columnspan=2)
ini_t2() # initial value
label_t2c=tk.Label(tab2,text='Rock Shear Strength\n(Upper limit)')
label_t2c.grid(row=4,column=0,columnspan=2)
s1='Class'
s2='c (MPa)'
s3='phi (deg)'
rock=['B','CH','CM','CL','D']
cc_r=np.array([6.0,4.0,2.4,1.0,0.4])
ph_r=np.array([65,55,45,10,30])
tree = ttk.Treeview(tab2)
tree['columns']=(1,2,3)
tree['show']='headings'
tree['height']=len(rock)
tree.column(1,anchor='center',width=50)
tree.column(2,anchor='center',width=50)
tree.column(3,anchor='center',width=50)
tree.heading(1,text=s1,anchor='center')
tree.heading(2,text=s2,anchor='center')
tree.heading(3,text=s3,anchor='center')
for i in range(0,len(rock)):
tree.insert(parent='',index='end',values=(rock[i],cc_r[i],ph_r[i]))
tree.grid(row=5,column=0,columnspan=2)
q_button=tk.Button(root,text='Quit',command=end_q)
q_button.pack()
root.mainloop()
if __name__ == '__main__': main()
以 上