Frame切换
在本文中,将介绍如何使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换。
1、Frame的tkraise() 方法介绍
通常,一个 Tkinter 应用程序由多个Frame组成。 而且您经常需要在Frame之间切换以显示与用户选择相关的Frame。
Tkinter 允许将Frame堆叠在一起。 要显示特定Frame,只需按堆叠顺序将一个放在另一个之上。 顶部Frame将可见。
要将Frame置于顶部,可以使用 Frame 小部件的 tkraise() 方法,如下所示:
1
|
frame.tkraise() |
2、tkraise用法示例
下面将实现一个温度转换小应用,华氏温度和摄氏温度分别使用两个不同的Frame,UI窗口组成如下:
ConverterFrame 将有两个实例,一个将温度从华氏温度转换为摄氏温度,另一个将温度从摄氏温度转换为华氏温度:
第一步,定义一个具有两个静态方法的 TemperatureConverter 类:fahrenheit_to_celsius 和 celsius_to_fahrenheit。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class TemperatureConverter: @staticmethod def fahrenheit_to_celsius(f, format = True ): result = (f - 32 ) * 5 / 9 if format : return f '{f} Fahrenheit = {result:.2f} Celsius' return result @staticmethod def celsius_to_fahrenheit(c, format = True ): result = c * 9 / 5 + 32 if format : return f '{c} Celsius = {result:.2f} Fahrenheit' return result |
如果忽略第二个参数或将 True 传递给它们,那么 fahrenheit_to_celsius 和 celsius_to_fahrenheit 方法将返回一个格式化字符串。 否则,他们会将结果作为数字返回。
第二步,定义将显示用于将温度从华氏温度转换为摄氏温度的 UI 的 ConverterFrame,反之亦然。
为此,需要通过将以下参数添加到 __init__()
方法来使 ConverterFrame 更加灵活:
- 将显示为华氏温度和摄氏度的字符串
- 用于转换温度的回调函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
class ConverterFrame(ttk.Frame): def __init__( self , container, unit_from, converter): super ().__init__(container) self .unit_from = unit_from self .converter = converter # field options options = { 'padx' : 5 , 'pady' : 0 } # temperature label self .temperature_label = ttk.Label( self , text = self .unit_from) self .temperature_label.grid(column = 0 , row = 0 , sticky = 'w' , * * options) # temperature entry self .temperature = tk.StringVar() self .temperature_entry = ttk.Entry( self , textvariable = self .temperature) self .temperature_entry.grid(column = 1 , row = 0 , sticky = 'w' , * * options) self .temperature_entry.focus() # button self .convert_button = ttk.Button( self , text = 'Convert' ) self .convert_button.grid(column = 2 , row = 0 , sticky = 'w' , * * options) self .convert_button.configure(command = self .convert) # result label self .result_label = ttk.Label( self ) self .result_label.grid(row = 1 , columnspan = 3 , * * options) # add padding to the frame and show it self .grid(column = 0 , row = 0 , padx = 5 , pady = 5 , sticky = "nsew" ) def convert( self , event = None ): """ Handle button click event """ try : input_value = float ( self .temperature.get()) result = self .converter(input_value) self .result_label.config(text = result) except ValueError as error: showerror(title = 'Error' , message = error) def reset( self ): self .temperature_entry.delete( 0 , "end" ) self .result_label.text = '' |
上面代码如何工作?
- 1)使用 unit_from 参数显示温度标签。
- 2)在 convert() 方法中调用 self.convert 回调将温度从一个单位转换为另一个单位。
- 3)定义 reset() 方法以在Frame从一个切换到另一个时清除条目小部件和结果标签。
第三,定义一个 ControlFrame 类,该类显示用于选择要显示的Frame的单选按钮。 ControFrame 类继承自 ttk.LabelFrame。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
class ControlFrame(ttk.LabelFrame): def __init__( self , container): super ().__init__(container) self [ 'text' ] = 'Options' # radio buttons self .selected_value = tk.IntVar() ttk.Radiobutton( self , text = 'F to C' , value = 0 , variable = self .selected_value, command = self .change_frame).grid(column = 0 , row = 0 , padx = 5 , pady = 5 ) ttk.Radiobutton( self , text = 'C to F' , value = 1 , variable = self .selected_value, command = self .change_frame).grid(column = 1 , row = 0 , padx = 5 , pady = 5 ) self .grid(column = 0 , row = 1 , padx = 5 , pady = 5 , sticky = 'ew' ) # initialize frames self .frames = {} self .frames[ 0 ] = ConverterFrame( container, 'Fahrenheit' , TemperatureConverter.fahrenheit_to_celsius) self .frames[ 1 ] = ConverterFrame( container, 'Celsius' , TemperatureConverter.celsius_to_fahrenheit) self .change_frame() def change_frame( self ): frame = self .frames[ self .selected_value.get()] frame.reset() frame.tkraise() |
上面代码如何工作?
- 每个单选按钮都有一个值 0 或 1。
- 创建 ConverterFrame 类的两个实例,一个负责将温度从华氏温度转换为摄氏温度,另一个负责将温度从摄氏温度转换为华氏温度。 另外,定义一个字典来存储这些Frame。 Frame的键与单选按钮的值相同。
- 单击单选按钮时,会调用 change_frame() 方法根据所选按钮的值从字典中选择相应的Frame。
- 调用Frame的 reset() 方法来重置输入字段和结果标签。 并且还调用 tkraise() 方法来显示Frame。
第四,定义从 tk.Tk 类继承的 App 类:
1
2
3
4
5
6
7
|
class App(tk.Tk): def __init__( self ): super ().__init__() self .title( 'Temperature Converter' ) self .geometry( '300x120' ) self .resizable( False , False ) |
最后,启动程序
1
2
3
4
|
if __name__ = = "__main__" : app = App() ControlFrame(app) app.mainloop() |
代码整合如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
import tkinter as tk from tkinter import ttk from tkinter.messagebox import showerror class TemperatureConverter: @staticmethod def fahrenheit_to_celsius(f, format = True ): result = (f - 32 ) * 5 / 9 if format : return f '{f} Fahrenheit = {result:.2f} Celsius' return result @staticmethod def celsius_to_fahrenheit(c, format = True ): result = c * 9 / 5 + 32 if format : return f '{c} Celsius = {result:.2f} Fahrenheit' return result class ConverterFrame(ttk.Frame): def __init__( self , container, unit_from, converter): super ().__init__(container) self .unit_from = unit_from self .converter = converter # field options options = { 'padx' : 5 , 'pady' : 0 } # temperature label self .temperature_label = ttk.Label( self , text = self .unit_from) self .temperature_label.grid(column = 0 , row = 0 , sticky = 'w' , * * options) # temperature entry self .temperature = tk.StringVar() self .temperature_entry = ttk.Entry( self , textvariable = self .temperature) self .temperature_entry.grid(column = 1 , row = 0 , sticky = 'w' , * * options) self .temperature_entry.focus() # button self .convert_button = ttk.Button( self , text = 'Convert' ) self .convert_button.grid(column = 2 , row = 0 , sticky = 'w' , * * options) self .convert_button.configure(command = self .convert) # result label self .result_label = ttk.Label( self ) self .result_label.grid(row = 1 , columnspan = 3 , * * options) # add padding to the frame and show it self .grid(column = 0 , row = 0 , padx = 5 , pady = 5 , sticky = "nsew" ) def convert( self , event = None ): """ Handle button click event """ try : input_value = float ( self .temperature.get()) result = self .converter(input_value) self .result_label.config(text = result) except ValueError as error: showerror(title = 'Error' , message = error) def reset( self ): self .temperature_entry.delete( 0 , "end" ) self .result_label.text = '' class ControlFrame(ttk.LabelFrame): def __init__( self , container): super ().__init__(container) self [ 'text' ] = 'Options' # radio buttons self .selected_value = tk.IntVar() ttk.Radiobutton( self , text = 'F to C' , value = 0 , variable = self .selected_value, command = self .change_frame).grid(column = 0 , row = 0 , padx = 5 , pady = 5 ) ttk.Radiobutton( self , text = 'C to F' , value = 1 , variable = self .selected_value, command = self .change_frame).grid(column = 1 , row = 0 , padx = 5 , pady = 5 ) self .grid(column = 0 , row = 1 , padx = 5 , pady = 5 , sticky = 'ew' ) # initialize frames self .frames = {} self .frames[ 0 ] = ConverterFrame( container, 'Fahrenheit' , TemperatureConverter.fahrenheit_to_celsius) self .frames[ 1 ] = ConverterFrame( container, 'Celsius' , TemperatureConverter.celsius_to_fahrenheit) self .change_frame() def change_frame( self ): frame = self .frames[ self .selected_value.get()] frame.reset() frame.tkraise() class App(tk.Tk): def __init__( self ): super ().__init__() self .title( 'Temperature Converter' ) self .geometry( '480x240' ) self .resizable( False , False ) if __name__ = = "__main__" : app = App() ControlFrame(app) app.mainloop() |
运行结果如下:
到此这篇关于Python Tkinter GUI编程实现Frame切换的文章就介绍到这了,更多相关Python Tkinter GUI Frame切换内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/wujuxKkoolerter/article/details/124367037