Skip to main content
 首页 » 编程设计

python之使用 Python 和 TKinter,如何重绘主屏幕

2025年05月04日9虾米姐

我有一个程序,其中主窗口分为两个部分,每个部分都有一组表单(简单标签/输入列)。默认情况下,第一部分中有 4 个这样的列,第二部分中有 2 个这样的列。我希望用户能够更改此比率。我想我已经准备好执行此操作的所有编程,只是无法让主窗口以正确的结构重绘。任何帮助将非常感激。谢谢。

我喜欢您的示例背后的简单性和想法,但是,我正在修改一些遗留代码并且没有时间将我的布局重写为定义。我试图创建一个只执行 grid_columnconfig() 的 def,但这没有用。我已经减少了代码,使其看起来像我正在使用的代码并且它也可以正常工作。如果您更改变量“max_pol_modules”,它会调整左侧的列与右侧的列,因此,我试图通过界面小部件更改此变量并重绘。

from Tkinter import * 
import tkFont 
 
max_pol_modules = 3 
max_bus_modules = 6 - max_pol_modules 
 
tech_green = '#5E9732' 
button_grey = '#666666' 
grey = '#777777' 
 
def config1(): 
    global max_pol_modules, max_bus_modules 
    max_pol_modules = 1 
    max_bus_modules = 6 - max_pol_modules 
#    print max_bus_modules 
 
#    left_frame.update() 
 
 
def config2(): 
    global max_pol_modules, max_bus_modules 
    max_pol_modules = 2 
    max_bus_modules = 6 - max_pol_modules 
#    print max_bus_modules 
 
 
def config3(): 
    global max_pol_modules, max_bus_modules 
    max_pol_modules = 3 
    max_bus_modules = 6 - max_pol_modules 
#    print max_bus_modules 
 
 
def config4(): 
    global max_pol_modules, max_bus_modules 
    max_pol_modules = 4 
    max_bus_modules = 6 - max_pol_modules 
#    print max_bus_modules 
 
def about(): 
    box.showinfo("About GUI","GE Bus Converter and Point of Load GUI") 
 
def bar(frame, row, span): 
    "create a bar to separate a section" 
    x = Frame(frame, relief=GROOVE, bd=2, width=86*(span+1), height=2) 
    x.grid(row=row, column=0, columnspan=10, pady=7, sticky=S+E) 
    x.grid_propagate(0) 
 
def bar2(frame, row, span): 
    "create a bar to separate a section" 
    x = Frame(frame, relief=GROOVE, bd=2, width=86*(span+1), height=2) 
    x.grid(row=row, column=0, columnspan=10, pady=3, sticky=S+E) 
    x.grid_propagate(0) 
 
def bar3(frame, row, span): 
    "create a bar to separate a section" 
    x = Frame(frame, relief=GROOVE, bd=2, width=100, height=2) 
    x.grid(row=row, column=0, columnspan=10, pady=7, sticky=S+E) 
    x.grid_propagate(0) 
 
root = Tk() 
 
menubar = Menu(root) 
 
submenu=Menu(menubar,tearoff=0) 
 
submenu2=Menu(submenu,tearoff=0) 
submenu2.add_command(label="1 - 5", command=config1) 
submenu2.add_command(label="2 - 4", command=config2) 
submenu2.add_command(label="3 - 3", command=config3) 
submenu2.add_command(label="4 - 2", command=config4) 
 
submenu_help = Menu(submenu,tearoff=0) 
submenu_help.add_command(label="About",command=about) 
 
 
submenu.add_cascade(label="Change Configuration",menu=submenu2) 
 
submenu.add_command(label="Exit", command=root.quit) 
 
menubar.add_cascade(label="Settings",menu=submenu) 
menubar.add_cascade(label="Help", menu=submenu_help) 
 
# display the menu 
root.config(menu=menubar) 
 
entry_wid = 6 
small_font = tkFont.Font(family='Arial', size=8, weight='bold') 
lite_font = tkFont.Font(family='Arial', size=9) 
large_font = tkFont.Font(family='Arial', size=9) 
heading_font = tkFont.Font(family='Arial', size=10, weight='bold') 
button_font = tkFont.Font(family='Arial', size=8, weight='bold') 
root.option_add('*font', lite_font) 
root.option_add('*background', '#C2C2C4') 
root.option_add('*Label.font', small_font) 
root.option_add('*Entry.background', 'white') 
root.option_add('*Button.font', button_font) 
root.option_add('*Button.background', button_grey) 
root.option_add('*Button.foreground', 'yellow') 
root.option_add('*Text.background', 'white') 
root.option_add('*Text.font', small_font) 
root.option_add('*ScrolledText.font', lite_font)  
 
left_frame = Frame(root) 
right_frame = Frame(root) 
 
pol_frame = Frame(left_frame, bd=2, relief=SUNKEN) 
x = Label(pol_frame, text="POL Address", anchor=E) 
x.grid(row=0, column=0, sticky=E) 
 
x = Label(pol_frame, text="Rtrim (Kohms)", anchor=E) 
x.grid(row=1, column=0, sticky=E) 
 
x = Label(pol_frame, text="Nominal Vout (V)", anchor=E) 
x.grid(row=2, column=0, sticky=E) 
 
bar2(pol_frame, 0, max_pol_modules) 
 
module_address = [] 
module_i2c = [] 
module_status = [] 
module_resistor = [] 
module_vout_nominal = [] 
for i in range(max_pol_modules): 
    # Module ID and address 
    f = Frame(pol_frame) 
    x = Label(f, text=i+1) 
    x.grid(row=0, column=0) 
    v = StringVar() 
    x = Entry(f, textvariable=v, width=3, justify=CENTER) 
    x.grid(row=0, column=1) 
    f.grid(row=0, column=i+1, pady=8, padx=20) 
    module_address.append(v) 
    module_i2c.append("") 
    module_status.append(0) 
    # module resistor 
    v = StringVar() 
    x = Entry(pol_frame, textvariable=v, width=entry_wid, justify=CENTER) 
    f = lambda event, module=i: change_resistor_event(event, module) 
    g = lambda value, m=i, o=16: set_change(value, m, o) 
    x.bind("<KeyRelease>", f, "+") 
    x.bind("<KeyRelease>", g, "+") 
    x.bind("<FocusOut>", f, "+") 
    x.grid(row=1, column=i+1, pady=0) 
    module_resistor.append(v) 
    # module nominal vout 
    v = StringVar() 
    x = Label(pol_frame, textvariable=v, width=entry_wid-1, 
          relief=SUNKEN, bg='#DDDDDD', font=lite_font) 
    x.grid(row=2, column=i+1, pady=0) 
    module_vout_nominal.append(v) 
 
bus_frame = Frame(left_frame, bd=2, relief=SUNKEN) 
#x = Label(bus_frame, text="Module (address)", anchor=E) 
#x.grid(row=0, column=max_pol_modules+1, sticky=E) 
x = Label(bus_frame, text="Bus Conv Address", anchor=E) 
x.grid(row=0, column=0, sticky=E) 
config_bus = [] 
r = 0 
 
#for i in range(max_pol_modules,max_pol_modules+max_bus_modules): 
for i in range(max_bus_modules): 
    # Module ID and address 
    f = Frame(bus_frame) 
    x = Label(f, text=i+5) 
    x.grid(row=0, column=0) 
    v = StringVar() 
    x = Entry(f, textvariable=v, width=3, justify=CENTER) 
    x.grid(row=0, column=1) 
    f.grid(row=0, column=i+2, pady=8, padx=20) 
    module_address.append(v) 
    module_i2c.append("") 
    module_status.append(0) 
 
 
bar2(bus_frame, r, max_bus_modules)  
r += 1 
 
# the measured values 
measure_info = ["Vout (V)", "Iout (A)", "Vin (V)", "Temp (degC)"] 
measures_bus = [] 
for mi in measure_info: 
    x = Label(bus_frame, text=mi, anchor=E) 
    x.grid(row=r, column=0, sticky=E) 
    m = [] 
    for j in range(max_bus_modules): 
        v = StringVar() 
        x = Label(bus_frame, textvariable=v, width=entry_wid-1, 
              relief=SUNKEN, bg='#DDDDDD', font=lite_font) 
        x.grid(row=r, column=j+2) 
        m.append(v) 
    measures_bus.append(m) 
    r += 1 
 
pol_frame.grid(row=0, column=0, sticky=N+W) 
 
bus_frame.grid(row=0, column=1, sticky=N+W) 
 
left_frame.grid(row=0, column=0, sticky=N) 
 
right_frame.grid(row=0, column=1, sticky=N) 
 
root.mainloop() 

编辑示例,其中需要删除 form[4] 和 form[5]。

import Tkinter as tk 
 
class App(tk.Tk): 
    def __init__(self, *args, **kwargs): 
        tk.Tk.__init__(self, *args, **kwargs) 
        self.forms = [] 
        self.toolbar = tk.Frame(self) 
        self.toolbar.pack(side="top", fill="x", expand=False) 
        button2 = tk.Button(self.toolbar, text="2 columns", command=self.layout2col) 
        button3 = tk.Button(self.toolbar, text="3 columns", command=self.layout3col) 
        button2.pack(side="left") 
        button3.pack(side="left") 
        self.forms_frame = tk.Frame(self, borderwidth=2, relief="groove") 
        self.forms_frame.pack(side="top", fill="both", expand="True", padx=2, pady=2) 
        for i in range(6): 
            frame = tk.LabelFrame(self.forms_frame, text="Form %s" % i) 
            self.forms.append(frame) 
            label = tk.Label(frame, text="Field %s" % i) 
            entry = tk.Entry(frame, width=20) 
            label.pack(side="left", fill="y") 
            entry.pack(side="left", fill="both", expand=True) 
 
        self.layout2col() 
 
    def layout3col(self): 
        self.forms[0].grid(column=0, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[1].grid(column=0, row=1, padx=4, pady=2, sticky="ew") 
        self.forms[2].grid(column=1, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[3].grid(column=1, row=1, padx=4, pady=2, sticky="ew") 
        self.forms[4].grid(column=2, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[5].grid(column=2, row=1, padx=4, pady=2, sticky="ew") 
        self.forms_frame.grid_columnconfigure(0, weight=1) 
        self.forms_frame.grid_columnconfigure(1, weight=1) 
        self.forms_frame.grid_columnconfigure(2, weight=1) 
 
    def layout2col(self): 
        self.forms[0].grid(column=0, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[1].grid(column=0, row=1, padx=4, pady=2, sticky="ew") 
        self.forms[2].grid(column=1, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[3].grid(column=1, row=1, padx=4, pady=2, sticky="ew") 
 
 
        self.forms_frame.grid_columnconfigure(0, weight=1) 
        self.forms_frame.grid_columnconfigure(1, weight=1) 
        self.forms_frame.grid_columnconfigure(2, weight=0) 
 
if __name__ == "__main__": 
    app = App() 
    app.mainloop() 

请您参考如下方法:

由于您使用的是网格几何管理器,因此您只需使用 grid 方法将它们放置在新的行和列中。您可能还需要调用 rowconfigure 和/或 columnconfigure 以将适当的权重附加到新的行和列。

下面是一个显示一般原则的人为示例。它可能会更有效率,但希望它能给你一个大概的想法:

import Tkinter as tk 
 
class App(tk.Tk): 
    def __init__(self, *args, **kwargs): 
        tk.Tk.__init__(self, *args, **kwargs) 
        self.forms = [] 
        self.toolbar = tk.Frame(self) 
        self.toolbar.pack(side="top", fill="x", expand=False) 
        button2 = tk.Button(self.toolbar, text="2 columns", command=self.layout2col) 
        button3 = tk.Button(self.toolbar, text="3 columns", command=self.layout3col) 
        button2.pack(side="left") 
        button3.pack(side="left") 
        self.forms_frame = tk.Frame(self, borderwidth=2, relief="groove") 
        self.forms_frame.pack(side="top", fill="both", expand="True", padx=2, pady=2) 
        for i in range(6): 
            frame = tk.LabelFrame(self.forms_frame, text="Form %s" % i) 
            self.forms.append(frame) 
            label = tk.Label(frame, text="Field %s" % i) 
            entry = tk.Entry(frame, width=20) 
            label.pack(side="left", fill="y") 
            entry.pack(side="left", fill="both", expand=True) 
 
        self.layout2col() 
 
    def layout3col(self): 
        self.forms[0].grid(column=0, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[1].grid(column=0, row=1, padx=4, pady=2, sticky="ew") 
        self.forms[2].grid(column=1, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[3].grid(column=1, row=1, padx=4, pady=2, sticky="ew") 
        self.forms[4].grid(column=2, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[5].grid(column=2, row=1, padx=4, pady=2, sticky="ew") 
        self.forms_frame.grid_columnconfigure(0, weight=1) 
        self.forms_frame.grid_columnconfigure(1, weight=1) 
        self.forms_frame.grid_columnconfigure(2, weight=1) 
 
    def layout2col(self): 
        self.forms[0].grid(column=0, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[1].grid(column=0, row=1, padx=4, pady=2, sticky="ew") 
        self.forms[2].grid(column=0, row=2, padx=4, pady=2, sticky="ew") 
        self.forms[3].grid(column=1, row=0, padx=4, pady=2, sticky="ew") 
        self.forms[4].grid(column=1, row=1, padx=4, pady=2, sticky="ew") 
        self.forms[5].grid(column=1, row=2, padx=4, pady=2, sticky="ew") 
        self.forms_frame.grid_columnconfigure(0, weight=1) 
        self.forms_frame.grid_columnconfigure(1, weight=1) 
        self.forms_frame.grid_columnconfigure(2, weight=0) 
 
if __name__ == "__main__": 
    app = App() 
    app.mainloop()