zoukankan      html  css  js  c++  java
  • tkinter的GUI设计:界面与逻辑分离(一)-- 初次见面

    PyQt实现界面与逻辑分离的设计很是方便,详情可以见我的第一篇博文。

    不过本文将使用python的标准库 tkinter,来实现界面与逻辑分离的GUI 设计。

    我们来设计一个很简单的程序:

      目的:长度单位英尺(feet)到米(meter)的转化

      实现:输入框输入英尺(feet),标签显示对应的长度米(meter)。可以点击按钮,亦可按回车键。

      说明:界面使用了 ttk.Frame 容器,各个部件的定位皆使用了 grid() 方法,3行3列

                       

      效果:如下

                           

      代码: 眼力好的你一定会发现,下面的代码风格有点像PyQt:

    import tkinter as tk
    from tkinter import ttk
    
    
    class Application(tk.Tk): # 继承自 tk.Tk
        '''界面、逻辑分离示例'''
        
        def __init__(self):
            '''初始化'''
            super().__init__() # 有点相当于tk.Tk()
            
            self.createWidgets()
    
        def createWidgets(self):
            '''界面'''
            self.mainframe = ttk.Frame(self, padding="3 3 12 12") # 注意ttk.Frame()的第一个参数为self,因为这个类继承自tk.Tk类
            self.mainframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
            self.mainframe.columnconfigure(0, weight=1)
            self.mainframe.rowconfigure(0, weight=1)
    
            # 定义了两个变量(下面会将它们绑定到输入部件 Entry 和标签部件 Label 上)
            # self.feet = StringVar()
            self.feet = tk.DoubleVar()
            self.meters = tk.StringVar()
    
            # 定义Entry部件,并把它赋给一个变量,方便在别处引用它。
            self.feet_entry = ttk.Entry(self.mainframe, width=7, textvariable=self.feet)
            self.feet_entry.grid(row=1, column=2, sticky=(tk.W, tk.E))
            self.feet_entry.focus()
    
            # 定义Label部件
            ttk.Label(self.mainframe, textvariable=self.meters).grid(row=2, column=2, sticky=(tk.W, tk.E))
            
            # 定义Button部件
            ttk.Button(self.mainframe, text="Calculate", command=self.calculate).grid(row=3, column=3, sticky=tk.W)
    
            # 定义三个Label部件
            ttk.Label(self.mainframe, text="feet").grid(row=1, column=3, sticky=tk.W)
            ttk.Label(self.mainframe, text="is equivalent to").grid(row=2, column=1, sticky=tk.E)
            ttk.Label(self.mainframe, text="meters").grid(row=2, column=3, sticky=tk.W)
            
            # 设置每格的 padding
            for child in self.mainframe.winfo_children(): 
                child.grid_configure(padx=5, pady=5)
                
            
            # 给窗口绑定回车键事件
            self.bind('<Return>', self.calculate)
    
        
        def calculate(self, *args): # 注意:参数必须是带!星!号!的 *args. 否则无论如何都会报类型错误:TypeError
            '''逻辑'''
            try:
                #value = float(self.feet.get()) # 如果前面定义为stringVar: self.feet = StringVar()
                value = self.feet.get()
                self.meters.set('{:.4f}'.format((0.3048 * value * 10000.0 + 0.5)/10000.0))
            except ValueError:
                pass
    
    
    if __name__ == '__maint__':
        # 实例化Application
        app = Application()
        
        # 设置窗口标题
        app.title("Feet to Meters")
        
        # 主消息循环:
        app.mainloop()

    参考:

    http://www.360doc.com/content/14/0328/02/9482_364311622.shtml

    http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868326118089581a091a04e4c30b2b7896392bdde5c000

  • 相关阅读:
    centos8 将SSSD配置为使用LDAP并要求TLS身份验证
    Centos8 搭建 kafka2.8 .net5 简单使用kafka
    .net core 3.1 ActionFilter 拦截器 偶然 OnActionExecuting 中HttpContext.Session.Id 为空字符串 的问题
    Springboot根据不同环境加载对应的配置
    VMware Workstation12 安装 Centos8.3
    .net core json配置文件小结
    springboot mybatisplus createtime和updatetime自动填充
    .net core autofac依赖注入简洁版
    .Net Core 使用 redis 存储 session
    .Net Core 接入 RocketMQ
  • 原文地址:https://www.cnblogs.com/hhh5460/p/5170251.html
Copyright © 2011-2022 走看看