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 相关文章推荐
pandas中的DataFrame按指定顺序输出所有列的方法
Apr 10 Python
Python爬虫抓取代理IP并检验可用性的实例
May 07 Python
深入浅析Python 中 is 语法带来的误解
May 07 Python
Python笔试面试题小结
Sep 07 Python
python自动点赞功能的实现思路
Feb 26 Python
使用已经得到的keras模型识别自己手写的数字方式
Jun 29 Python
15个应该掌握的Jupyter Notebook使用技巧(小结)
Sep 23 Python
详解pandas中利用DataFrame对象的.loc[]、.iloc[]方法抽取数据
Dec 13 Python
十个Python自动化常用操作,即拿即用
May 10 Python
Python实现视频中添加音频工具详解
Dec 06 Python
pandas进行数据输入和输出的方法详解
Mar 23 Python
使用Python获取字典键对应值的方法
Apr 26 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删除非空目录的函数代码小结
2013/02/28 PHP
使用Sphinx对索引进行搜索
2013/06/25 PHP
析构函数与php的垃圾回收机制详解
2013/10/28 PHP
PHP学习笔记(一) 简单了解PHP
2014/08/04 PHP
php微信开发之批量生成带参数的二维码
2016/06/26 PHP
php5对象复制、clone、浅复制与深复制实例详解
2019/08/14 PHP
jquery 与NVelocity 产生冲突的解决方法
2011/06/13 Javascript
window.location.href = window.location.href 跳转无反应 a超链接onclick事件写法
2013/08/21 Javascript
Javascript控制div属性动态变化实例分析
2015/10/08 Javascript
JS+Canvas绘制时钟效果
2020/08/20 Javascript
jQuery实现的网格线绘制方法
2016/06/20 Javascript
vue.js表格组件开发的实例详解
2016/10/12 Javascript
JS实现用户注册时获取短信验证码和倒计时功能
2016/10/27 Javascript
微信小程序 聊天室简单实现
2017/04/19 Javascript
iscroll.js滚动加载实例详解
2017/07/18 Javascript
pm2 部署 node的三种方法示例
2017/10/20 Javascript
JavaScript实现树的遍历算法示例【广度优先与深度优先】
2017/10/26 Javascript
基于openlayers4实现点的扩散效果
2020/08/17 Javascript
微信小程序webview组件交互,内联h5页面并网页实现微信支付实现解析
2019/08/16 Javascript
Vue中消息横向滚动时setInterval清不掉的问题及解决方法
2019/08/23 Javascript
vue el-table实现行内编辑功能
2019/12/11 Javascript
JavaScript实现图片伪异步上传过程解析
2020/04/10 Javascript
Python中几种导入模块的方式总结
2017/04/27 Python
Python中数组,列表:冒号的灵活用法介绍(np数组,列表倒序)
2018/04/18 Python
详解Django解决ajax跨域访问问题
2018/08/24 Python
Python 写入训练日志文件并控制台输出解析
2019/08/13 Python
西班牙最大的婴儿用品网上商店:Bebitus
2019/05/30 全球购物
英国亚马逊官方网站:Amazon.co.uk
2019/08/09 全球购物
求职信的要素有哪些呢
2013/12/26 职场文书
《雨霖铃》教学反思
2014/02/22 职场文书
安全温馨提示语大全
2015/07/14 职场文书
学习十八大的感悟
2015/08/11 职场文书
建立共青团委员会的请示
2019/04/02 职场文书
详解如何在Canvas中添加事件的方法
2021/04/17 Javascript
MySQL删除和插入数据很慢的问题解决
2021/06/03 MySQL
css中有哪些方式可以隐藏页面元素及区别
2022/06/16 HTML / CSS