python 调用 shell 命令,制作用户界面
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()