python 呼叫 shell 命令,製作使用者介面
阿新 • • 發佈:2021-10-29
1. python呼叫shell指令: os.system
格式為 os.system('command')
import os os.system('make') flag0 = flag[0]; flag1 = flag[1]; flag2 = flag[2]; flag3 = flag[3]; flag4 = flag[4] os.system('echo %d %d %d %d %d > output/cin.massfit' % (flag0, flag1, flag2, flag3, flag4)) os.system('./massfit.x < output/cin.massfit')
如上,可以在 python 中命令 shell 編譯其他 c++ 程式,然後執行該程式。值得注意的是上面的第 4 排,可以將 python 中的變數的值傳給 shell。這樣,可以用 python tinker 寫一個使用者介面,然後讓使用者在介面上點點點或者輸入引數,再按某個鍵,底層的c++程式就去跑。我是這樣給 c++ 程式新增介面的。
2. python 製作使用者介面
tinker 模組可以製作簡單的使用者介面,我試過幾個,錄在這裡
2.1 文字編輯器
# A simple text file editor from tkinter import * from tkinter.scrolledtext import ScrolledText def load(): with open(filename.get()) as file: contents.delete('1.0', END) contents.insert(INSERT, file.read()) def save(): with open(filename.get(), 'w') as file: file.write(contents.get('1.0', END)) top = Tk() top.resizable(False, False) top.title("Simple Editor") contents = ScrolledText() contents.pack( side = BOTTOM, expand=True, fill=BOTH) filename = Entry() filename.pack(side=LEFT, expand=True, fill=X) Button(text='Open', command=load).pack(side=LEFT) Button(text='Save', command=save).pack(side=LEFT) #ttk.Label(top, text="A Label").grid(column=0, row=0) mainloop()
2.2 點選按鍵,文字改變
# click a button and a text changes import tkinter as tk from tkinter import ttk win = tk.Tk() win.title("Python GUI") a_label = ttk.Label(win, text="A Label") a_label.grid(column=0, row=0) def click_me(): action.configure(text="** I have been Clicked! **") a_label.configure(foreground='red') a_label.configure(text='A Red Label') action = ttk.Button(win, text="Click Me!", command=click_me) action.grid(column=1, row=0) win.mainloop()
2.3 輸入人名,自動打招呼
# Input a name and say hello to the person
import tkinter as tk
from tkinter import ttk
win = tk.Tk()
def click_me():
action.configure(text='Hello ' + name.get())
# the button click event is a callback function
ttk.Label(win, text="Enter a name:").grid(column=0, row=0)
action = ttk.Button(win, text="Click Me!", command=click_me)
action.grid(column=1, row=1)
action.configure(state='disabled') # Disable the Button Widget
name = tk.StringVar() # Note: tk.StringVar
name_entered = ttk.Entry(win, width=12, textvariable=name)
name_entered.grid(column=0, row=1)
name_entered.focus()
win.mainloop()
2.4 還有點問題的畫圖介面
import tkinter
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import numpy as np
root = tkinter.Tk()
root.wm_title("Embedding in Tk")
fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
canvas.draw()
# pack_toolbar=False will make it easier to use a layout manager later on.
toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
toolbar.update()
canvas.mpl_connect(
"key_press_event", lambda event: print(f"you pressed {event.key}"))
canvas.mpl_connect("key_press_event", key_press_handler)
button = tkinter.Button(master=root, text="Quit", command=root.quit)
# Packing order is important. Widgets are processed sequentially and if there
# is no space left, because the window is too small, they are not displayed.
# The canvas is rather flexible in its size, so we pack it last which makes
# sure the UI controls are displayed as long as possible.
button.pack(side=tkinter.BOTTOM)
toolbar.pack(side=tkinter.BOTTOM, fill=tkinter.X)
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
tkinter.mainloop()
2.5 最後是原子核質量液滴模型擬合介面,需要搭配我寫的 c++ 擬合程式使用
#coding=utf-8
import os
# Liquid Drop Model, fit the AME2012 mass data with (optionally) these terms:
# volume, surface, symmetry, Coulumb, pairing
import matplotlib
matplotlib.use('TkAgg') # matplotlib 後端設定為 TkAgg,才能與 tkinter 一致
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # 設定 canvas
from matplotlib.figure import Figure # 宣告 Figure
from tkinter import *
root = Tk() # Tk 例項
root.title("Residual error of liquid drop model of nuclear masses") # title
f = Figure(figsize=(8,5), dpi=100)
fplot = f.add_subplot(111)
def _destroyWindow():
root.quit()
root.destroy()
color = ['#d9d9d9','green']; flag=[0,0,0,0,0]
def volume():
flag[0] = ( flag[0]+1 )%2 # jump between 0,1
button0.config(bg = color[flag[0]], activebackground=color[flag[0]])
def surface():
flag[1] = ( flag[1]+1 )%2
button1.config(bg = color[flag[1]], activebackground=color[flag[1]])
def symmetry():
flag[2] = ( flag[2]+1 )%2
button2.config(bg = color[flag[2]], activebackground=color[flag[2]])
def coulomb():
flag[3] = ( flag[3]+1 )%2
button3.config(bg = color[flag[3]], activebackground=color[flag[3]])
def pairing():
flag[4] = ( flag[4]+1 )%2
button4.config(bg = color[flag[4]], activebackground=color[flag[4]])
def cal_Bres():
# run c++ code and get data
os.system('make')
flag0 = flag[0]; flag1 = flag[1]; flag2 = flag[2]; flag3 = flag[3]; flag4 = flag[4]
os.system('echo %d %d %d %d %d > output/cin.massfit' % (flag0, flag1, flag2, flag3, flag4))
os.system('./massfit.x < output/cin.massfit')
def draw_ZBres():
cal_Bres()
data = np.loadtxt("output/res.txt")
Z = data[:,0]; N = data[:, 1]; A = data[:, 2]; Bres = data[:, 3]
fplot.clear(); fplot.set_xlabel("Z"); fplot.set_ylabel("Bres = Bexp. - Bth. (MeV)")
fplot.scatter(Z,Bres,s=1); canvs.draw()
def draw_NBres():
cal_Bres()
data = np.loadtxt("output/res.txt")
Z = data[:,0]; N = data[:, 1]; A = data[:, 2]; Bres = data[:, 3]
fplot.clear(); fplot.set_xlabel("Z"); fplot.set_ylabel("Bres = Bexp. - Bth. (MeV)")
fplot.scatter(N,Bres,s=1); canvs.draw()
canvs = FigureCanvasTkAgg(f,root)
canvs.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
button0 = Button(root, text='volume', command=volume); button0.pack(side=LEFT)
button1 = Button(root, text="surface", command=surface); button1.pack(side=LEFT)
button2 = Button(root, text="symmetry", command=symmetry); button2.pack(side=LEFT)
button3 = Button(root, text="coulomb", command=coulomb); button3.pack(side=LEFT)
button4 = Button(root, text="pairing", command=pairing); button4.pack(side=LEFT)
button_draw_ZBres = Button(root, text="Bres v.s. Z", command=draw_ZBres).pack(side=LEFT)
button_draw_ZBres = Button(root, text="Bres v.s. N", command=draw_NBres).pack(side=LEFT)
root.mainloop()