对于之前长度单位转换器的改写

之前写了一个很朴素的长度单位换算器(用Python写一个朴素的长度单位转换器),现在进行了一次改写,对比效果如下(分别是1.0、1.1、2.0版本):

image.png

image.png

image.png

可以转换的选项增加,版面排布进行了改善,使用滚动条将常规输入规范化,可以实现双向换算,之前的只能单向换算为米。还有很大的改良空间,可以继续改写。

Python3代码:

'''###############################################################################
# Name: UnitsExchange2.0
# Author: Wenchao Liu
# Date: 2018-11-27
# Description: To exchange the different units
#                    Debug in python 3.5.3
###############################################################################'''

from tkinter import *

#### 创建一个单位转换的类 ####
class UnitExchange():
    '''这是一个用于单位换算的类,实现常用单位的互相换算'''
    def __init__(self):
        '''属性初始化'''
        #### 创建主窗口 ####
        self.root = Tk()
        self.root.title('长度单位换算器')
        #### 创建变量 ####
        self.target_value = StringVar()    # 输入数值
        self.result_value = StringVar()     # 输出数值
        self.target_unit = StringVar()      # 输入单位
        self.result_unit = StringVar()       # 输出单位
        #### 创建输入输出的显示框架组件 ####
        '''包含数值输入框、输入单位显示框、等号标签、结果数值显示框和结果单位显示框'''
        self.top_frame = Frame(self.root)    # 创建一个框架(纯容器)
        # 数值输入框
        self.target_entry = Entry(self.top_frame, width=18, textvariable=self.target_value)    
        self.target_entry.grid(column=1, row=1, sticky=W)    # 第1列1行,罗盘式靠西
        # 输入单位显示框
        self.tar_unit_list = Listbox(self.top_frame, height=1, width=4)   
        self.tar_unit_list.grid(column=2, row=1, sticky=W)
        # 等号标签
        self.equal_label = Label(self.top_frame, text='=')
        self.equal_label.grid(column=3, row=1)
        # 结果数值显示框
        self.res_value_list = Listbox(self.top_frame, height=1, width=18)
        self.res_value_list.grid(column=4, row=1, sticky=E)
        # 结果单位显示框
        self.res_unit_list = Listbox(self.top_frame, height=1, width=4)    
        self.res_unit_list.grid(column=5, row=1, sticky=E)
        self.top_frame.pack(side=TOP)    # 将整个框架显示到主窗口顶端      
        #### 输入选项框架组件 ####
        '''包含输入单位选项列表框和列表框的滚动条,将输入单位可选内容显示出来,可以进行竖直方向滚动。
           调用的方法有:targetUnit()'''
        self.target_frame = Frame(self.root)
        # 滚动条
        self.target_scroll = Scrollbar(self.target_frame)   
        self.target_scroll.pack(side=RIGHT, fill=Y)
        # 输入单位选项列表框
        self.target_list = Listbox(self.target_frame, height=5, width= 18, yscrollcommand=self.target_scroll.set)
        self.target_list.bind('', self.targetUnit)    # 双击列表框中的选项,调用targetUnit()方法
        self.target_scroll.config(command=self.target_list.yview)    # 竖直方向滚动
        self.target_list.pack(side=LEFT, fill = BOTH)        
        self.target_frame.pack(side=LEFT)    # 整个框架显示到主窗口左侧
        #### 输出选项框架组件 ####
        '''包含结果单位选项列表框和列表框的滚动条,将输出单位可选内容显示出来,可以进行竖直方向滚动。
           调用的方法有:resultUnit()'''
        # 滚动条
        self.result_frame = Frame(self.root)
        self.result_scroll = Scrollbar(self.result_frame)    
        self.result_scroll.pack(side=RIGHT, fill=Y)
        # 输出单位选项列表框
        self.result_list = Listbox(self.result_frame, height=5, width= 18, yscrollcommand=self.result_scroll.set)
        self.result_list.bind('', self.resultUnit)  
        self.result_scroll.config(command=self.result_list.yview)    # 竖直方向滚动
        self.result_list.pack(side=LEFT, fill = BOTH)  
        self.result_frame.pack(side=RIGHT)    # 整个框架显示到主窗口右侧
        #### 创建按键 ####
        '''点击换算按钮,进行单位换算。调用的方法有:calculateUnit()'''
        self.calculate = Button(self.root, text='换算', command=self.calculateUnit)
        self.calculate.pack(side=BOTTOM)
        # 如果用户按下回车键,和点击换算按钮一样,启动换算
        # self.root.bind('', self.calculateUnit)
        #### 单位列表 ####
        self.units = ['fm', 'pm', 'nm', 'um','mm','cm', 'm', 'km']
        #### GUI初始化 ####
        '''将列表框所有选项内容显示出来。调用方法有:self.targetList(),self.resultList() '''
        self.targetList()    # 调用targetList()方法,将输入选项列表框的内容显示出来
        self.resultList()     # 调用resultList()方法,将结果选项列表框的内容显示出来

    #### 定义类的方法 ####
    '''curselection() 返回列表框中的行号值,get()在没有传递参数时,获得列表框所有内容,将行号作为参数
      传递,则获得行号对应选项的内容。定义的方法有:targetUnit(), resultUnit(), targetList(), resultList(),
      switch2Meter(), switch2Other(), calculateUnit()'''
    def targetUnit(self, ev=None):
        '''得到转换前的单位'''
        self.target_unit.set( self.target_list.get(self.target_list.curselection()))
        self.tar_unit_list.insert(END,  self.target_unit.get())
        # 将选定的输入单位插入到输入单位选项显示框(在第一个框架组件里)

    def resultUnit(self, ev=None):
        '''得到转换后的单位'''
        self.result_unit.set(self.result_list.get(self.result_list.curselection()))
        self.res_unit_list.insert(END, self.result_unit.get())
        # 将选定的输出单位插入到输出单位选项显示框(在第一个框架组件里)

    def targetList(self, ev=None):
        '''显示转换前的所有单位选项'''
        tar_list = self.units
        for item in tar_list:
            # 将单位内容插入到输入单位选项列表框(在第二个框架组件里)
            self.target_list.insert(END, item)

    def resultList(self, ev=None):
        '''显示转换后的所有单位选项'''
        res_list = self.units
        for item in res_list:
            # 将单位内容插入到结果单位选项列表框(在第三个框架组件里)
            self.result_list.insert(END, item)
   
    def switch2Meter(self, var, x):
         '''用字典实现switch功能,将其他长度单位换算为米'''
         return {'cm'  : lambda x: x/100.0, 
                    'mm' : lambda x: x/1000.0,
                    'km'  : lambda x: x*1000.0,
                    'um'  : lambda x: x/1E6,
                    'nm'  : lambda x: x/1E9,
                    'A'     : lambda x: x/1E10,
                    'pm'  : lambda x: x/1E12,
                    'fm'   : lambda x: x/1E15,
                    'm'    : lambda x: x,
                   }[var](x)

    def switch2Other(self, var, x):
        '''用字典实现switch功能,将米换算为其他长度单位'''
        return {'cm'  : lambda x: x*100.0, 
                    'mm' : lambda x: x*1000.0,
                    'km'  : lambda x: x/1000.0,
                    'um'  : lambda x: x*1E6,
                    'nm'  : lambda x: x*1E9,
                    'A'     : lambda x: x*1E10,
                    'pm'  : lambda x: x*1E12,
                    'fm'   : lambda x: x*1E15,
                    'm'    : lambda x: x,
                   }[var](x)
        
    def calculateUnit(self):
        '''根据需求,对单位进行换算,调用方法有:switch2Meter(),switch2Other()'''
        try:
            '''异常处理'''
            tar_value = float(self.target_value.get())    # 获取输入值
            tar_unit = self.target_unit.get()    # 获取输入单位
            res_unit = self.result_unit.get()    #  获取输出单位
            if (res_unit == 'm'):
                # 如果是转换为米,则直接转换
                self.result_value.set(self.switch2Meter(tar_unit, tar_value))
            else:
                # 如果不是转换为米,先转换为米作为过渡,再转换为其他单位
                temp = StringVar()   # 过渡量
                temp.set(self.switch2Meter(tar_unit, tar_value))
                temp_value = float(temp.get())
                self.result_value.set(self.switch2Other(res_unit, temp_value))
            '''输出数值插入到输出数值显示框,calculateUnit()方法被调用时,数值显示出来'''
            self.res_value_list.insert(END, self.result_value.get())
        except ValueError:
            pass

#### 主函数 ####                 
def main():
    x = UnitExchange()    # 类实例化
    mainloop()    # 窗口消息循环

if __name__=='__main__':
    main()

你可能感兴趣的:(对于之前长度单位转换器的改写)