Tkinter中的交换

3 投票
2 回答
1593 浏览
提问于 2025-04-17 03:53

我有一个简单的Tkinter程序,用Python写的,它可以把英尺转换成米。这个程序里有一个标签,一个输入英尺的框,一个带有凹边的米数框,还有三个按钮:退出、转换和交换。

我现在想弄明白怎么让“交换”按钮实现它的功能。也就是说,交换窗口中英尺和米的位置,这样你就可以输入米数,然后点击转换,它就会把米数转换成英尺。

其实我只需要知道怎么交换位置(计算的部分其实挺简单的),但我就是想不出逻辑该怎么写。下面是我目前的代码:

import Tkinter

win = Tkinter.Tk()
win.title('Converter')

Row1 =Tkinter.Frame(win)
blank = Tkinter.Label(Row1, text=' ', font=('Courier New', 30))
blank.pack()
Row1.pack()

label = Tkinter.Label(win, text='Convert Between Feet and Meters', font=('Courier
New',30,"bold"))
label.pack()

def convert():
    st = entry1.get()
    v = eval(st)
    if type(v) != type('Hello'):
        answer.config(text=str(v*.3048))

def swap():
    #here's where I need to figure out how to swap


Row2 = Tkinter.Frame(win)
fLabel = Tkinter.Label(Row2, text='Feet', justify='right', font=('Courier New', 30))
entry1 = Tkinter.Entry(Row2, width = 12, font=('Courier New', 30))
fLabel.pack(side='left')
entry1.pack(side='right')
Row2.pack()

Row3 = Tkinter.Frame(win)
mLabel = Tkinter.Label(Row3, text='Meters', justify='right', font=('Courier New',30))
answer = Tkinter.Label(Row3, text='0', width=12, relief='sunken', font=('Courier New',
30))
mLabel.pack(side='left')
answer.pack(side='left')
Row3.pack()

Row4 = Tkinter.Frame(win)
quit = Tkinter.Button(Row4, text='Quit', command = win.destroy, font=('Courier
New',30))
convert = Tkinter.Button(Row4, text='Convert', command = convert, font=('Courier
New',30))
swap = Tkinter.Button(Row4, text='Swap', command=swap, font=('Courier New',30))
quit.pack(side='left')
convert.pack(side='left')
swap.pack(side='right')
Row4.pack()

Row5 = Tkinter.Frame(win)
blank2 = Tkinter.Label(Row5, text=' ', font=('Courier New', 30))
blank2.pack()
Row5.pack()

win.mainloop()

(第一个和最后一个框只是用来留白的)非常感谢任何帮助!

2 个回答

0

使用下标的表格比把选择硬编码到代码中更灵活。下面的例子使用下标 t0 和 t1 来索引一个标签表(比如英尺、米)和一个转换因子表(比如 0.3048、3.2808)。如果你想添加其他转换,比如摄氏度到华氏度,你可以直接在表格中添加,而不需要修改代码。

还有几点需要注意:

  • 在 Python 中,交换两个变量的值可以用复合赋值的方式(a, b = b, a),而不是使用临时变量(t = a, a = b, b = t)。
  • 如果同样的内容重复出现很多次(比如字体规格 - 哇,真大又丑!),可以考虑把它变成一个变量。这样更容易修改,也更简洁。
  • 不需要为了留白而创建空框架,直接使用内边距就可以了。
  • 网格布局可以让英尺和米的标签/数值整齐对齐。

下面的交换函数使用了表格/下标的方法:

from Tkinter import Tk, Frame, Label, Entry, Button

def convert():
    global t1
    st = entry1.get()
    v = eval(st)
    if type(v) != type('Hello'):
        answer.config(text=str(v*factor[t1]), anchor='w')

def swap():
    global t1, t2
    t1, t2 = t2, t1
    Label1.config(text=lbl[t1])
    Label2.config(text=lbl[t2])
    answer.config(text='')

win = Tk()
win.title('Converter')
fspec = ('Courier New', 30)

label = Label(win, text='Convert Between Feet and Meters', font=fspec+('bold',))
label.pack(pady=30)

Row2 = Frame(win)
Row2.pack()
t1, t2 = 0, 1
lbl = ('Feet', 'Meters')
factor = (.3048, 1./.3048)
Label1 = Label(Row2, text=lbl[t1], justify='right', font=fspec)
entry1 = Entry(Row2, width = 12, font=fspec)
Label2 = Label(Row2, text=lbl[t2], justify='right', font=fspec)
answer = Label(Row2, width=12, relief='sunken', font=fspec)
Label1.grid(row=2, column=2)
entry1.grid(row=2, column=4)
Label2.grid(row=4, column=2)
answer.grid(row=4, column=4)

Row4 = Frame(win)
quitb = Button(Row4, text='Quit', command = win.destroy, font=fspec)
convert = Button(Row4, text='Convert', command = convert, font=fspec)
swap = Button(Row4, text='Swap', command=swap, font=fspec)
quitb.pack(side='left')
convert.pack(side='left')
swap.pack(side='right')
Row4.pack(pady=30)

win.mainloop()
3

创建一个变量,用来存储你正在转换的内容,然后让 swap 函数来改变这个变量并更新标签的显示内容。要更改标签的文字,你可以使用 label['text'] = '新文字' 或者 label.configure(text='新文字')。下面是你代码的一个可用修改版本:

import Tkinter

inputmode = 'feet' # This is the variable that stores what you are converting from


win = Tkinter.Tk()
win.title('Converter')

Row1 =Tkinter.Frame(win)
blank = Tkinter.Label(Row1, text=' ', font=('Courier New', 30))
blank.pack()
Row1.pack()

label = Tkinter.Label(win, text='Convert Between Feet and Meters', font=('Courier New',30,"bold"))
label.pack()

def convert():
    st = entry1.get()
    v = eval(st)
    if type(v) != type('Hello'):
        if inputmode == 'feet': # check which way to convert
            answer.config(text=str(v*.3048))
        else:
            answer.config(text=str(v*3.28))

def swap():
    global inputmode
    if inputmode == 'meters':
        inputmode = 'feet'
        fLabel['text'] = 'Feet' # Changes the text of the label
        mLabel['text'] = 'Metres'
    else:
        inputmode = 'meters'
        fLabel['text'] = 'Metres'
        mLabel['text'] = 'Feet'


Row2 = Tkinter.Frame(win)
fLabel = Tkinter.Label(Row2, text='Feet', justify='right', font=('Courier New', 30))
entry1 = Tkinter.Entry(Row2, width = 12, font=('Courier New', 30))
fLabel.pack(side='left')
entry1.pack(side='right')
Row2.pack()

Row3 = Tkinter.Frame(win)
mLabel = Tkinter.Label(Row3, text='Meters', justify='right', font=('Courier New',30))
answer = Tkinter.Label(Row3, text='0', width=12, relief='sunken', font=('Courier New', 30))
mLabel.pack(side='left')
answer.pack(side='left')
Row3.pack()

Row4 = Tkinter.Frame(win)
quit = Tkinter.Button(Row4, text='Quit', command = win.destroy, font=('Courier New',30))
convert = Tkinter.Button(Row4, text='Convert', command = convert, font=('Courier New',30))
swap = Tkinter.Button(Row4, text='Swap', command=swap, font=('Courier New',30))
quit.pack(side='left')
convert.pack(side='left')
swap.pack(side='right')
Row4.pack()

Row5 = Tkinter.Frame(win)
blank2 = Tkinter.Label(Row5, text=' ', font=('Courier New', 30))
blank2.pack()
Row5.pack()

win.mainloop()

撰写回答