Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换


Posted in Python onApril 24, 2022

Frame切换

在本文中,将介绍如何使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换。

1、Frame的tkraise() 方法介绍

通常,一个 Tkinter 应用程序由多个Frame组成。 而且您经常需要在Frame之间切换以显示与用户选择相关的Frame。

Tkinter 允许将Frame堆叠在一起。 要显示特定Frame,只需按堆叠顺序将一个放在另一个之上。 顶部Frame将可见。

要将Frame置于顶部,可以使用 Frame 小部件的 tkraise() 方法,如下所示:

frame.tkraise()

2、tkraise用法示例

下面将实现一个温度转换小应用,华氏温度和摄氏温度分别使用两个不同的Frame,UI窗口组成如下:

Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换

ConverterFrame 将有两个实例,一个将温度从华氏温度转换为摄氏温度,另一个将温度从摄氏温度转换为华氏温度:

Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换

第一步,定义一个具有两个静态方法的 TemperatureConverter 类:fahrenheit_to_celsius 和 celsius_to_fahrenheit。

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 更加灵活:

  • 将显示为华氏温度和摄氏度的字符串
  • 用于转换温度的回调函数。
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。

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 类:

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Temperature Converter')
        self.geometry('300x120')
        self.resizable(False, False)

最后,启动程序

if __name__ == "__main__":
    app = App()
    ControlFrame(app)
    app.mainloop()

代码整合如下:

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 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换

 到此这篇关于Python Tkinter GUI编程实现Frame切换的文章就介绍到这了!


Tags in this post...

Python 相关文章推荐
Python中字符串的处理技巧分享
Sep 17 Python
Python机器学习之决策树算法
Dec 22 Python
scrapy爬虫实例分享
Dec 28 Python
浅谈解除装饰器作用(python3新增)
Oct 15 Python
python使用Pandas库提升项目的运行速度过程详解
Jul 12 Python
Python入门Anaconda和Pycharm的安装和配置详解
Jul 16 Python
python模拟鼠标点击和键盘输入的操作
Aug 04 Python
Python 中的 global 标识对变量作用域的影响
Aug 12 Python
Pytorch 之修改Tensor部分值方式
Dec 27 Python
Python基于requests库爬取网站信息
Mar 02 Python
Django在Model保存前记录日志实例
May 14 Python
Python编写可视化界面的全过程(Python+PyCharm+PyQt)
May 17 Python
在 Python 中利用 Pool 进行多线程
Apr 24 #Python
Python何绘制带有背景色块的折线图
python中Pyqt5使用Qlabel标签播放视频
Apr 22 #Python
Python使用MapReduce进行简单的销售统计
python使用pycharm安装pyqt5以及相关配置
Python使用DFA算法过滤内容敏感词
python游戏开发之pygame实现接球小游戏
Apr 22 #Python
You might like
php初学者写及时补给skype用户充话费的小程序
2008/11/02 PHP
PHPExcel在linux环境下导出报500错误的解决方法
2017/01/26 PHP
Z-Blog中用到的js代码
2007/03/15 Javascript
javascript数组快速打乱重排的方法
2014/01/02 Javascript
iframe如何动态创建及释放其所占内存
2014/09/03 Javascript
Javascript中数组sort和reverse用法分析
2014/12/30 Javascript
js实现仿QQ秀换装效果的方法
2015/03/04 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
2016/07/24 Javascript
微信小程序 获取设备信息 API实例详解
2016/10/02 Javascript
javascript匀速动画和缓冲动画详解
2016/10/20 Javascript
headjs实现网站并行加载但顺序执行JS
2016/11/29 Javascript
使用smartupload组件实现jsp+jdbc上传下载文件实例解析
2017/01/05 Javascript
详谈js中window.location.search的用法和作用
2017/02/13 Javascript
基于angular2 的 http服务封装的实例代码
2017/06/29 Javascript
elementui的默认样式修改方法
2018/02/23 Javascript
浅谈super-vuex使用体验
2018/06/25 Javascript
Vue.js中使用iView日期选择器并设置开始时间结束时间校验功能
2018/08/12 Javascript
2019年度web前端面试题总结(主要为Vue面试题)
2020/01/12 Javascript
vue计算属性+vue中class与style绑定(推荐)
2020/03/30 Javascript
JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
2020/04/13 Javascript
js屏蔽F12审查元素,禁止修改页面代码等实现代码
2020/10/02 Javascript
Vue仿Bibibili首页的问题
2021/01/21 Vue.js
使用Python快速搭建HTTP服务和文件共享服务的实例讲解
2018/06/04 Python
pytorch中tensor的合并与截取方法
2018/07/26 Python
将python图片转为二进制文本的实例
2019/01/24 Python
Python单元测试工具doctest和unittest使用解析
2019/09/02 Python
Puccini乌克兰:购买行李箱、女士手袋网上商店
2020/08/06 全球购物
随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
2014/01/18 面试题
竞职演讲稿范文
2014/01/11 职场文书
初中学生期末评语
2014/04/24 职场文书
产品设计开发计划书
2014/05/07 职场文书
离婚协议书范文2015
2015/01/26 职场文书
详解python的内存分配机制
2021/05/10 Python
javascript对象3个属性特征
2021/11/17 Javascript
科普 | 业余无线电知识-波段篇
2022/02/18 无线电