python远程连接KVM
使用的库函数
import tkinter as tk import libvirt from tkinter import messagebox import tkinter.font as tkFont from tkinter import * import time import paramiko
获得窗体尺寸
def get_window_size(win, update=True): """ 获得窗体的尺寸 """ if update: win.update() return win.winfo_width(), win.winfo_height(), win.winfo_x(), win.winfo_y()
设置虚拟机类
# 虚拟机参数 class VCPU: def __init__(self): self.NAME = '' # 姓名 self.IP = '' self.cpun = 0 # cpu个数 self.cpurate = 0 # cpu使用率 self.memoryrate = 0 self.memory = 0 self.stats = '' self.node = 0
创建虚拟机
# 创建镜像 def createjingxiang(name,node): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) a = 'node' + str(node) b = 'qemu-img create -f qcow2 ' + str(name) + '.qcow2 10G' ssh.connect(hostname=a, username='mpiuser', password='123456') try: stdin, stdout, stderr = ssh.exec_command(b) ssh.close() except Exception as e: tk.messagebox.showinfo(title='错误提示框', message=str(e)) # 写xml文件 def writexml(name,cpun,memory): file_object = open('ubuntu1.xml','rU') file_context = file_object.read() n="<name>"+str(name)+"</name>" c="<vcpu placement='static'>"+str(int(cpun))+"</vcpu>" q="<source file='/home/mpiuser/"+str(name)+".qcow2'/> " m="<memory unit='KiB'>"+str(memory*1024)+"</memory> <currentMemory unit='KiB'>"+str(memory*1024)+"</currentMemory> " a=file_context.replace("<name>ubuntu1</name>",n,1) a=a.replace("<vcpu placement='static'>1</vcpu>",c,1) a=a.replace("<memory unit='KiB'>1048576</memory> <currentMemory unit='KiB'>1048576</currentMemory> ",m,1) a=a.replace("<source file='/home/mpiuser/ubuntu.qcow2'/> ",q,1) return a # 创建虚拟机 def create_machine(cpulist, kvmnet): flag = False def addcpu(): flag = False a = VCPU() a.cpun = int(_cpun.get()) a.NAME = _name.get() a.memory = int(_memory.get()) # mb NODE = int(_node.get()) # 输入node节点 conn = libvirt.open(kvmnet[NODE - 1]) NODE_free_memory = conn.getFreeMemory() / (1024 ** 2) # Mb NODE_cpu_nums = conn.getCPUMap()[0] def change(): tk.messagebox.showinfo(title='消息提示框', message='虚拟机创建成功') dom = conn.lookupByName(a.NAME) dom.create() cpulist.append(a) if a.memory < NODE_free_memory and a.cpun < NODE_cpu_nums: xmltext = writexml(a.NAME, a.cpun, a.memory) a.node = NODE try: createjingxiang(a.NAME, a.node) conn.defineXML(xmltext) # 创建虚拟机 createframe1 = tk.Toplevel() createframe1.geometry("%dx%d" % (500, 500)) # 窗体尺寸 frameerror = tk.Frame(createframe1, bg="white") frameerror.pack() tk.Label(frameerror, text="请手动安装虚拟机操作系统! ", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=20, pady=10) tk.Button(frameerror, text='操作系统安装完成', width=10, height=1, bg='white', relief=GROOVE, command=change).pack( side=tk.BOTTOM, padx=10) except Exception as e: tk.messagebox.showinfo(title='错误提示框', message=str(e)) return else: for i in range(len(kvmnet)): conn = libvirt.open(kvmnet[i]) if a.memory < conn.getFreeMemory() / (1024 ** 2) and a.cpun < conn.getCPUMap()[0]: xmltext = writexml(a.NAME, a.cpun, a.memory) a.node = i + 1 try: createjingxiang(a.NAME, a.node) conn.defineXML(xmltext) # 创建虚拟机 createframe1 = tk.Toplevel() createframe1.geometry("%dx%d" % (400, 300)) # 窗体尺寸 frameerror = tk.Frame(createframe1, bg="white") frameerror.pack(fill=tk.X) tk.Label(frameerror, text="经过调整后,请在节点node"+str(a.node)+"请手动安装虚拟机操作系统! ", bg="white", fg='black', height=2, width=30, font=tkFont.Font(family="微软雅黑", size=8)).pack() # side=tk.LEFT, padx=20, pady=10 tk.Button(frameerror, text='操作系统安装完成', width=20, height=2, bg='white', relief=GROOVE, command=change).pack() except Exception as e: tk.messagebox.showinfo(title='错误提示框', message=str(e)) return if a.node == 0: tk.messagebox.showinfo(title='消息提示框', message='虚拟机设置有误,请重新创建') create_machine(cpulist, kvmnet) createframe = tk.Toplevel() createframe.geometry("%dx%d" % (400, 300)) # 窗体尺寸 screenwidth1 = createframe.winfo_screenwidth() screenheight1 = createframe.winfo_screenheight() width1, height1 = get_window_size(createframe)[:2] size1 = '%dx%d+%d+%d' % (width1, height1, (screenwidth1 - width1) / 2, (screenheight1 - height1) / 3) createframe.geometry(size1) # 将窗体移动到屏幕中央 # 美观,填充间隔 frame_seperator3 = tk.Frame(createframe, height=20, bg="whitesmoke") frame_seperator3.pack(fill=tk.X) frame_seperator1 = tk.Frame(createframe, width=20, bg='whitesmoke') frame_seperator1.pack(side=tk.RIGHT, fill=tk.Y) frame_seperator2 = tk.Frame(createframe, width=20, bg='whitesmoke') frame_seperator2.pack(side=tk.LEFT, fill=tk.Y) frame1 = tk.Frame(createframe, bg="white") frame1.pack(fill=tk.X) tk.Label(frame1, text="节点:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=36, pady=10) _node = tk.Entry(frame1, width=27) _node.pack(side=tk.LEFT) frame2 = tk.Frame(createframe, bg="white") frame2.pack(fill=tk.X) tk.Label(frame2, text="虚拟机名称:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=20, pady=10) _name = tk.Entry(frame2, width=27) _name.pack(side=tk.LEFT) frame3 = tk.Frame(createframe, bg="white") frame3.pack(fill=tk.X) tk.Label(frame3, text="CPU个数:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=25, pady=10) _cpun = tk.Entry(frame3, width=27) _cpun.pack(side=tk.LEFT) frame4 = tk.Frame(createframe, bg="white") frame4.pack(fill=tk.X) tk.Label(frame4, text="内存分配:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=25, pady=10) _memory = tk.Entry(frame4, width=27) _memory.pack(side=tk.LEFT) frame5 = tk.Frame(createframe, bg="white") frame5.pack(fill=tk.X) tk.Button(frame5, text='确认', width=10, height=1, bg='white', relief=GROOVE, command=addcpu).pack( side=tk.RIGHT, padx=10)
删除虚拟机
# 删除虚拟机 def delete_machine(cpulist): cpulist = update_machine(cpulist) delframe = tk.Toplevel() delframe.geometry("%dx%d" % (400, 300)) screenwidth1 = delframe.winfo_screenwidth() screenheight1 = delframe.winfo_screenheight() width1, height1 = get_window_size(delframe)[:2] size1 = '%dx%d+%d+%d' % (width1, height1, (screenwidth1 - width1) / 2, (screenheight1 - height1) / 3) delframe.geometry(size1) delframe.title("删除虚拟机") frame1 = tk.Frame(delframe, bg="white") frame1.pack(fill=tk.X) tk.Label(frame1, text="节点:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=36, pady=10) _node = tk.Entry(frame1, width=27) _node.pack(side=tk.LEFT) frame2 = tk.Frame(delframe, bg="white") frame2.pack(fill=tk.X) tk.Label(frame2, text="虚拟机名称:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=20, pady=10) _name = tk.Entry(frame2, width=27) _name.pack(side=tk.LEFT) namelist = [] for i in range(len(cpulist)): namelist.append(cpulist[i].NAME) def dele(): try: nameset = set(namelist) node_ = int(_node.get()) # 输入虚拟机所在节点号 name_ = _name.get() # 输入的虚拟机名称 if name_ in nameset: # 如果输入的虚拟机存在 conn = libvirt.open(kvmnet[node_ - 1]) dom = conn.lookupByName(name_) dom.destroy() # 对所有虚拟机都是先关闭再删除 保证任何状态下的虚拟机都可以被删除 dom.undefine() conn.close() messagebox.showinfo("提示", "删除成功!") else: messagebox.showinfo("警告", "虚拟机不存在!") except Exception as e: tk.messagebox.showinfo(title='错误提示框', message=str(e)) return tk.Button(delframe, text='确认', width=10, height=1, bg='white', command=dele).pack( side=tk.RIGHT, padx=10)
开启虚拟机
# 开启虚拟机 def open_machine(cpulist): kvmlist = update_machine(cpulist) delframe = tk.Toplevel() delframe.geometry("%dx%d" % (400, 300)) screenwidth1 = delframe.winfo_screenwidth() screenheight1 = delframe.winfo_screenheight() width1, height1 = get_window_size(delframe)[:2] size1 = '%dx%d+%d+%d' % (width1, height1, (screenwidth1 - width1) / 2, (screenheight1 - height1) / 3) delframe.geometry(size1) delframe.title("开启虚拟机") frame1 = tk.Frame(delframe, bg="white") frame1.pack(fill=tk.X) tk.Label(frame1, text="节点:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=36, pady=10) _node = tk.Entry(frame1, width=27) _node.pack(side=tk.LEFT) frame2 = tk.Frame(delframe, bg="white") frame2.pack(fill=tk.X) tk.Label(frame2, text="虚拟机名称:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=20, pady=10) _name = tk.Entry(frame2, width=27) _name.pack(side=tk.LEFT) namelist = [] for i in range(len(kvmlist)): namelist.append(kvmlist[i].NAME) def creat(): try: nameset = set(namelist) node_ = int(_node.get()) # 输入虚拟机所在节点号 name_ = _name.get() # 输入的虚拟机名称 if name_ in nameset: # 如果输入的虚拟机存在 conn = libvirt.open(kvmnet[node_ - 1]) dom = conn.lookupByName(name_) dom.create() conn.close() messagebox.showinfo("提示", "开启成功!") else: messagebox.showinfo("警告", "虚拟机不存在!") except Exception as e: tk.messagebox.showinfo(title='错误提示框', message=str(e)) return tk.Button(delframe, text='确认', width=10, height=1, bg='white', command=creat).pack( side=tk.RIGHT, padx=10)
关闭虚拟机
def shutdown_machine(cpulist): cpulist = update_machine(cpulist) delframe = tk.Toplevel() delframe.geometry("%dx%d" % (400, 300)) screenwidth1 = delframe.winfo_screenwidth() screenheight1 = delframe.winfo_screenheight() width1, height1 = get_window_size(delframe)[:2] size1 = '%dx%d+%d+%d' % (width1, height1, (screenwidth1 - width1) / 2, (screenheight1 - height1) / 3) delframe.geometry(size1) delframe.title("关闭虚拟机") frame1 = tk.Frame(delframe, bg="white") frame1.pack(fill=tk.X) tk.Label(frame1, text="节点:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=36, pady=10) _node = tk.Entry(frame1, width=27) _node.pack(side=tk.LEFT) frame2 = tk.Frame(delframe, bg="white") frame2.pack(fill=tk.X) tk.Label(frame2, text="虚拟机名称:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=20, pady=10) _name = tk.Entry(frame2, width=27) _name.pack(side=tk.LEFT) namelist = [] for i in range(len(cpulist)): namelist.append(cpulist[i].NAME) def dele(): try: nameset = set(namelist) node_ = int(_node.get()) # 输入虚拟机所在节点号 name_ = _name.get() # 输入的虚拟机名称 if name_ in nameset: # 如果输入的虚拟机存在 conn = libvirt.open(kvmnet[node_ - 1]) dom = conn.lookupByName(name_) dom.destroy() conn.close() messagebox.showinfo("提示", "关闭成功!") else: messagebox.showinfo("警告", "虚拟机不存在!") except Exception as e: tk.messagebox.showinfo(title='错误提示框', message=str(e)) return tk.Button(delframe, text='确认', width=10, height=1, bg='white', command=dele).pack( side=tk.RIGHT, padx=10)
暂停虚拟机
def suspend_machine(cpulist): cpulist = update_machine(cpulist) delframe = tk.Toplevel() delframe.geometry("%dx%d" % (400, 300)) screenwidth1 = delframe.winfo_screenwidth() screenheight1 = delframe.winfo_screenheight() width1, height1 = get_window_size(delframe)[:2] size1 = '%dx%d+%d+%d' % (width1, height1, (screenwidth1 - width1) / 2, (screenheight1 - height1) / 3) delframe.geometry(size1) delframe.title("暂停虚拟机") frame1 = tk.Frame(delframe, bg="white") frame1.pack(fill=tk.X) tk.Label(frame1, text="节点:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=36, pady=10) _node = tk.Entry(frame1, width=27) _node.pack(side=tk.LEFT) frame2 = tk.Frame(delframe, bg="white") frame2.pack(fill=tk.X) tk.Label(frame2, text="虚拟机名称:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=20, pady=10) _name = tk.Entry(frame2, width=27) _name.pack(side=tk.LEFT) namelist = [] for i in range(len(cpulist)): namelist.append(cpulist[i].NAME) def suspend(): try: nameset = set(namelist) print(nameset) node_ = int(_node.get()) name_ = _name.get() # 输入的虚拟机名称 if name_ in nameset: # 如果输入的虚拟机存在 conn = libvirt.open(kvmnet[node_ - 1]) dom = conn.lookupByName(name_) dom.suspend() messagebox.showinfo("提示", "暂停成功!") else: messagebox.showinfo("警告", "虚拟机不存在!") except Exception as e: tk.messagebox.showinfo(title='错误提示框', message=str(e)) return tk.Button(delframe, text='确认', width=10, height=1, bg='white', command=suspend).pack( side=tk.RIGHT, padx=10)
运行虚拟机
def resume_machine(cpulist): cpulist = update_machine(cpulist) delframe = tk.Toplevel() delframe.geometry("%dx%d" % (400, 300)) screenwidth1 = delframe.winfo_screenwidth() screenheight1 = delframe.winfo_screenheight() width1, height1 = get_window_size(delframe)[:2] size1 = '%dx%d+%d+%d' % (width1, height1, (screenwidth1 - width1) / 2, (screenheight1 - height1) / 3) delframe.geometry(size1) delframe.title("运行虚拟机") frame1 = tk.Frame(delframe, bg="white") frame1.pack(fill=tk.X) tk.Label(frame1, text="节点:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=36, pady=10) _node = tk.Entry(frame1, width=27) _node.pack(side=tk.LEFT) frame2 = tk.Frame(delframe, bg="white") frame2.pack(fill=tk.X) tk.Label(frame2, text="虚拟机名称:", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=8)).pack(side=tk.LEFT, padx=20, pady=10) _name = tk.Entry(frame2, width=27) _name.pack(side=tk.LEFT) namelist = [] for i in range(len(cpulist)): namelist.append(cpulist[i].NAME) def resume(): try: nameset = set(namelist) print(nameset) node_ = int(_node.get()) name_ = _name.get() # 输入的虚拟机名称 if name_ in nameset: # 如果输入的虚拟机存在 conn = libvirt.open(kvmnet[node_ - 1]) dom = conn.lookupByName(name_) dom.resume() conn.close() messagebox.showinfo("提示", "运行成功!") else: messagebox.showinfo("警告", "虚拟机不存在!") except Exception as e: tk.messagebox.showinfo(title='错误提示框', message=str(e)) return tk.Button(delframe, text='确认', width=10, height=1, bg='white', command=resume).pack( side=tk.RIGHT, padx=10)
更新虚拟机状态
def update_machine(cpulist): cpulist = [] for i in range(len(kvmnet)): try: conn = libvirt.open(kvmnet[i]) except: continue domlist = conn.listAllDomains() nbcore = conn.getInfo()[2] # 用于计算cpu使用率 for dom in domlist: ubuntu0 = VCPU() ubuntu0.node = i + 1 state0, reason0 = dom.state() ubuntu0.NAME = dom.name() ubuntu0.IP = ' ' # if state0 == 1 and reason0 != 1: print(ubuntu0.node, ubuntu0.NAME, dom.state()) if state0 == 1: ubuntu0.stats = "运行中" ubuntu0.cpun = dom.maxVcpus() cpu_use_ago = dom.info()[4] time.sleep(1) cpu_use_now = dom.info()[4] diff_use = cpu_use_now - cpu_use_ago ubuntu0.cpurate = round(100 * diff_use / (1 * nbcore * 10 ** 9), 2) ubuntu0.memory = dom.maxMemory() instance_memory = dom.memoryStats() print(instance_memory) unused_memory = instance_memory["unused"] # 未被使用得内存 total_memory = instance_memory["actual"] # 被分配的 ubuntu0.memoryrate = round((1 - unused_memory / total_memory) * 100, 2) elif state0 == 5: # ubuntu0.stats = "关闭中" + str(state0) + "," + str(reason0) ubuntu0.stats = "关闭中" else: # ubuntu0.stats = "暂停中" + str(state0) + "," + str(reason0) ubuntu0.stats = "暂停中" cpulist.append(ubuntu0) conn.close() return cpulist
显示信息
def showcpustate(parent,cpulist,i): if cpulist[i].stats == '运行中': frame = tk.Frame(parent, bg="white") tk.Label(frame, text="node" + str(cpulist[i].node), bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11, weight=tkFont.BOLD)).pack(side=tk.LEFT, padx=10, pady=5) tk.Label(frame, text="虚拟机名称: "+cpulist[i].NAME, bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11, weight=tkFont.BOLD)).pack(side=tk.LEFT,padx=10, pady=5) tk.Label(frame, text="cpu数量: "+str(cpulist[i].cpun), bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11)).pack(side=tk.LEFT, padx=5) tk.Label(frame, text="内存总量: " + str(cpulist[i].memory)+"kB", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11)).pack(side=tk.LEFT, padx=5) tk.Label(frame, text="cpu使用率: " + str(cpulist[i].cpurate)+"%", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11)).pack(side=tk.LEFT, padx=5) tk.Label(frame, text="内存使用率: " + str(cpulist[i].memoryrate)+"%", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11)).pack(side=tk.LEFT, padx=5) tk.Label(frame, text="状态: " +cpulist[i].stats, bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11)).pack(side=tk.LEFT, padx=5) else: frame = tk.Frame(parent, bg="white") tk.Label(frame, text="node" + str(cpulist[i].node), bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11, weight=tkFont.BOLD)).pack(side=tk.LEFT, padx=10, pady=5) tk.Label(frame, text="虚拟机名称: "+cpulist[i].NAME, bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11, weight=tkFont.BOLD)).pack(side=tk.LEFT,padx=10, pady=5) tk.Label(frame, text="状态: " +cpulist[i].stats, bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=11)).pack(side=tk.LEFT, padx=10) return frame
更新显示信息
def update_info(parent,cpulist): cpulist = update_machine(cpulist) for widget in parent.winfo_children(): widget.destroy() print("虚拟机个数:", len(cpulist)) messagebox.showinfo("提示", "虚拟机个数为"+str(len(cpulist))) for i in range(len(cpulist)): frame_name = "frame"+str(i) frame_name = showcpustate(parent, cpulist, i).pack(fill=tk.X)
主函数
if __name__ == '__main__': # 例子 global cpulist, kvmnet cpulist = [] kvmnet = ['qemu+ssh://mpiuser@node1/system', 'qemu+ssh://mpiuser@node2/system', 'qemu+ssh://mpiuser@node3/system'] root = tk.Tk() root.geometry("%dx%d" % (2800, 3000)) # 窗体尺寸 screenwidth = root.winfo_screenwidth() screenheight = root.winfo_screenheight() width, height = get_window_size(root)[:2] size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 3) root.geometry(size) # 将窗体移动到屏幕中央 root.title("虚拟机控制器") # 窗体标题 # 核心框架 frame_main = tk.Frame(root, bg="whitesmoke") frame_main.propagate(False) frame_main.pack(expand=tk.YES, fill=tk.BOTH) frame_maintop = tk.Frame(frame_main, height=180, bg="white") frame_maintop.pack(side=tk.TOP, fill=tk.X, padx=30) tk.Label(frame_maintop, text="管理中心", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=16, weight=tkFont.BOLD)).pack(anchor=tk.W, padx=20, pady=5) bu2 = tk.Button(frame_maintop, text='创建虚拟机', width=25, height=2, bg='white', relief=FLAT, font=tkFont.Font(family="微软雅黑", size=12), command=lambda: create_machine(cpulist, kvmnet)).pack(padx=10, pady=5, side=LEFT) bu3 = tk.Button(frame_maintop, text='删除虚拟机', width=25, height=2, bg='white', relief=FLAT, font=tkFont.Font(family="微软雅黑", size=12), command=lambda: delete_machine(cpulist)).pack(padx=10, pady=5, side=LEFT) bu4 = tk.Button(frame_maintop, text='开启虚拟机', width=25, height=2, bg='white', relief=FLAT, font=tkFont.Font(family="微软雅黑", size=12), command=lambda: open_machine(cpulist)).pack(padx=10, pady=5, side=LEFT) bu5 = tk.Button(frame_maintop, text='关闭虚拟机', width=25, height=2, bg='white', relief=FLAT, font=tkFont.Font(family="微软雅黑", size=12), command=lambda: shutdown_machine(cpulist)).pack(padx=10, pady=5, side=LEFT) bu7 = tk.Button(frame_maintop, text='暂停虚拟机', width=25, height=2, bg='white', relief=FLAT, font=tkFont.Font(family="微软雅黑", size=12), command=lambda: suspend_machine(cpulist)).pack(padx=10, pady=5, side=LEFT) bu6 = tk.Button(frame_maintop, text='运行虚拟机', width=25, height=2, bg='white', relief=FLAT, font=tkFont.Font(family="微软雅黑", size=12), command=lambda: resume_machine(cpulist)).pack(padx=10,pady=5, side=LEFT) frame_maintop.propagate(False) # 上下分界 frame_seperator1 = tk.Frame(frame_main, height=20, bg='whitesmoke') frame_seperator1.pack(side=tk.BOTTOM, fill=tk.X) frame_mainbottom = tk.Frame(frame_main, height=200, bg="white") frame_mainbottom.pack(side=tk.BOTTOM, expand=tk.YES, fill=tk.BOTH) frame_mainbottomtop = tk.Frame(frame_mainbottom, bg="white", height=80) frame_mainbottomtop.pack(fill=tk.X, padx=20, pady=5) frame_mainrightbot = tk.Frame(frame_mainbottom, bg="white", height=80) frame_mainrightbot.pack(fill=tk.X, padx=20, pady=5) tk.Label(frame_mainbottomtop, text="监控中心", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=16, weight=tkFont.BOLD)).pack(side=LEFT, padx=20) bu8 = tk.Button(frame_mainbottomtop, text='更新', width=10, height=1, bg='white', relief=GROOVE , command=lambda: update_info(frame_mainrightbot, cpulist)) bu8.pack(side=RIGHT, padx=20) # 填充间隔 frame_seperator2 = tk.Frame(frame_mainbottom, width=2, bg="whitesmoke") frame_seperator2.pack(fill=tk.Y) root.mainloop()