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装饰器 免去调用父类构造函数的麻烦
May 18 Python
Python使用add_subplot与subplot画子图操作示例
Jun 01 Python
python list格式数据excel导出方法
Oct 31 Python
Python除法之传统除法、Floor除法及真除法实例详解
May 23 Python
使用python socket分发大文件的实现方法
Jul 08 Python
python使用openCV遍历文件夹里所有视频文件并保存成图片
Jan 14 Python
pytorch构建多模型实例
Jan 15 Python
详解Python中的分支和循环结构
Feb 11 Python
Python模拟伯努利试验和二项分布代码实例
May 27 Python
查看keras的默认backend实现方式
Jun 19 Python
python中tkinter窗口位置\坐标\大小等实现示例
Jul 09 Python
Python爬取某拍短视频
Jun 11 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
sqlyog 中文乱码问题的设置方法
2008/10/19 PHP
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
PHP动态柱状图实现方法
2015/03/30 PHP
JavaScipt基本教程之前言
2008/01/16 Javascript
JavaScript的Cookies
2008/01/16 Javascript
isArray()函数(JavaScript中对象类型判断的几种方法)
2009/11/26 Javascript
使用JS进行目录上传(相当于批量上传)
2010/12/05 Javascript
利用jquery写的左右轮播图特效
2014/02/12 Javascript
JavaScript子窗口调用父窗口变量和函数的方法
2015/10/09 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
2016/05/24 Javascript
浅谈Javascript中的函数、this以及原型
2016/10/09 Javascript
BootStrap实现邮件列表的分页和模态框添加邮件的功能
2016/10/13 Javascript
javascript设计模式之模块模式学习笔记
2017/02/15 Javascript
node.js+express+mySQL+ejs+bootstrop实现网站登录注册功能
2018/01/12 Javascript
分析javascript原型及原型链
2018/03/18 Javascript
详解es6超好用的语法糖Decorator
2018/08/01 Javascript
element vue validate验证名称重复 输入框与后台重复验证 特殊字符 字符长度 及注意事项小结【实例代码】
2018/11/20 Javascript
浅析Vue.js中v-bind v-model的使用和区别
2018/12/04 Javascript
JQuery获取可视区尺寸和文档尺寸及制作悬浮菜单示例
2019/05/14 jQuery
如何让微信小程序页面之间的通信不再变困难
2019/06/03 Javascript
express + jwt + postMan验证实现持久化登录
2019/06/05 Javascript
使用typescript改造koa开发框架的实现
2020/02/04 Javascript
[02:09]EHOME夺得首届辉夜杯冠军—现场颁奖仪式
2015/12/28 DOTA
[46:57]EG vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python简单图片操作:打开\显示\保存图像方法介绍
2017/11/23 Python
Python3模拟curl发送post请求操作示例
2019/05/03 Python
解决Python二维数组赋值问题
2019/11/28 Python
如何理解python面向对象编程
2020/06/01 Python
在css3中background-clip属性与background-origin属性的用法介绍
2012/11/13 HTML / CSS
HTML5的postMessage的使用手册
2018/12/19 HTML / CSS
逃课打麻将检讨书
2014/10/05 职场文书
复兴之路观后感
2015/06/02 职场文书
公诉意见书范文
2015/06/05 职场文书
windows安装python超详细图文教程
2021/05/21 Python
MySQL实战记录之如何快速定位慢SQL
2022/03/23 MySQL
sql server偶发出现死锁的解决方法
2022/04/10 SQL Server