Python单位转换工具
下面是一个功能完整的单位转换工具,使用Python和Tkinter实现图形界面。该工具支持多种物理量的转换,包括长度、质量、温度、速度、面积和体积等。
import tkinter as tk
from tkinter import ttk, messagebox
import math
class UnitConverter:
def __init__(self, root):
self.root = root
self.root.title("多功能单位转换工具")
self.root.geometry("700x500")
self.root.resizable(True, True)
self.root.configure(bg="#f0f8ff")
# 设置主题样式
self.style = ttk.Style()
self.style.theme_use("clam")
self.style.configure("TFrame", background="#f0f8ff")
self.style.configure("TLabel", background="#f0f8ff", font=("Arial", 10))
self.style.configure("TButton", font=("Arial", 10, "bold"), background="#4b86b4", foreground="white")
self.style.configure("TCombobox", font=("Arial", 10))
self.style.configure("Header.TLabel", font=("Arial", 14, "bold"), foreground="#2a4d69")
# 创建主框架
self.main_frame = ttk.Frame(root, padding=20)
self.main_frame.pack(fill=tk.BOTH, expand=True)
# 标题
title_label = ttk.Label(self.main_frame, text="多功能单位转换工具", style="Header.TLabel")
title_label.pack(pady=(0, 20))
# 创建转换类别选择
category_frame = ttk.Frame(self.main_frame)
category_frame.pack(fill=tk.X, pady=10)
ttk.Label(category_frame, text="转换类别:").pack(side=tk.LEFT, padx=(0, 10))
self.category_var = tk.StringVar()
categories = ["长度", "质量", "温度", "速度", "面积", "体积"]
self.category_combo = ttk.Combobox(category_frame, textvariable=self.category_var,
values=categories, state="readonly", width=15)
self.category_combo.pack(side=tk.LEFT)
self.category_combo.current(0)
self.category_combo.bind("<<ComboboxSelected>>", self.update_units)
# 创建输入框架
input_frame = ttk.Frame(self.main_frame)
input_frame.pack(fill=tk.X, pady=10)
# 输入值
ttk.Label(input_frame, text="输入值:").grid(row=0, column=0, padx=(0, 10), sticky=tk.W)
self.input_var = tk.StringVar()
self.input_entry = ttk.Entry(input_frame, textvariable=self.input_var, width=15, font=("Arial", 10))
self.input_entry.grid(row=0, column=1, sticky=tk.W)
# 输入单位
ttk.Label(input_frame, text="从:").grid(row=0, column=2, padx=(10, 10))
self.from_unit_var = tk.StringVar()
self.from_unit_combo = ttk.Combobox(input_frame, textvariable=self.from_unit_var,
state="readonly", width=15)
self.from_unit_combo.grid(row=0, column=3, sticky=tk.W)
# 输出单位
ttk.Label(input_frame, text="到:").grid(row=0, column=4, padx=(10, 10))
self.to_unit_var = tk.StringVar()
self.to_unit_combo = ttk.Combobox(input_frame, textvariable=self.to_unit_var,
state="readonly", width=15)
self.to_unit_combo.grid(row=0, column=5, sticky=tk.W)
# 转换按钮
convert_button = ttk.Button(input_frame, text="转换", command=self.convert)
convert_button.grid(row=0, column=6, padx=(20, 0))
# 创建输出框架
output_frame = ttk.Frame(self.main_frame)
output_frame.pack(fill=tk.X, pady=20)
ttk.Label(output_frame, text="结果:").pack(side=tk.LEFT, anchor=tk.N, padx=(0, 10))
self.result_text = tk.Text(output_frame, height=6, width=50, font=("Arial", 10),
bg="white", relief=tk.SUNKEN, padx=10, pady=10)
self.result_text.pack(fill=tk.BOTH, expand=True, side=tk.LEFT)
self.result_text.config(state=tk.DISABLED)
# 创建历史记录框架
history_frame = ttk.LabelFrame(self.main_frame, text="转换历史", padding=10)
history_frame.pack(fill=tk.BOTH, expand=True, pady=10)
# 历史记录列表
self.history_listbox = tk.Listbox(history_frame, font=("Arial", 9), bg="white",
relief=tk.SUNKEN, selectbackground="#d3e0ea")
self.history_listbox.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# 历史记录控制按钮
button_frame = ttk.Frame(history_frame)
button_frame.pack(fill=tk.X, pady=(5, 0))
clear_button = ttk.Button(button_frame, text="清除历史", command=self.clear_history)
clear_button.pack(side=tk.RIGHT)
# 初始化单位
self.update_units()
self.conversion_history = []
# 状态栏
self.status_var = tk.StringVar()
self.status_var.set("就绪")
status_bar = ttk.Label(root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
status_bar.pack(side=tk.BOTTOM, fill=tk.X)
# 设置初始焦点
self.input_entry.focus_set()
# 绑定回车键
self.root.bind("<Return>", lambda event: self.convert())
def update_units(self, event=None):
"""根据选择的类别更新单位列表"""
category = self.category_var.get()
if category == "长度":
units = ["米 (m)", "千米 (km)", "厘米 (cm)", "毫米 (mm)", "英寸 (in)", "英尺 (ft)", "码 (yd)", "英里 (mile)"]
elif category == "质量":
units = ["克 (g)", "千克 (kg)", "毫克 (mg)", "磅 (lb)", "盎司 (oz)", "吨 (t)"]
elif category == "温度":
units = ["摄氏度 (°C)", "华氏度 (°F)", "开尔文 (K)"]
elif category == "速度":
units = ["米/秒 (m/s)", "千米/小时 (km/h)", "英里/小时 (mph)", "节 (kn)", "马赫 (Ma)"]
elif category == "面积":
units = ["平方米 (m²)", "平方千米 (km²)", "公顷 (ha)", "平方英里 (mi²)", "英亩 (acre)", "平方英尺 (ft²)"]
elif category == "体积":
units = ["立方米 (m³)", "升 (L)", "毫升 (mL)", "加仑 (gal)", "立方英尺 (ft³)"]
else:
units = []
self.from_unit_combo["values"] = units
self.to_unit_combo["values"] = units
if units:
self.from_unit_combo.current(0)
self.to_unit_combo.current(1)
def convert(self):
"""执行单位转换"""
# 获取输入值
try:
input_value = float(self.input_var.get())
except ValueError:
messagebox.showerror("输入错误", "请输入有效的数字")
self.status_var.set("错误:请输入有效的数字")
return
# 获取单位和类别
from_unit = self.from_unit_var.get()
to_unit = self.to_unit_var.get()
category = self.category_var.get()
if not from_unit or not to_unit:
messagebox.showerror("单位错误", "请选择源单位和目标单位")
self.status_var.set("错误:请选择源单位和目标单位")
return
# 执行转换
try:
if category == "长度":
result = self.convert_length(input_value, from_unit, to_unit)
elif category == "质量":
result = self.convert_mass(input_value, from_unit, to_unit)
elif category == "温度":
result = self.convert_temperature(input_value, from_unit, to_unit)
elif category == "速度":
result = self.convert_speed(input_value, from_unit, to_unit)
elif category == "面积":
result = self.convert_area(input_value, from_unit, to_unit)
elif category == "体积":
result = self.convert_volume(input_value, from_unit, to_unit)
else:
result = input_value
# 显示结果
self.display_result(input_value, from_unit, result, to_unit)
# 添加到历史记录
history_entry = f"{input_value} {from_unit} = {result:.6f} {to_unit} [{category}]"
self.conversion_history.append(history_entry)
self.history_listbox.insert(tk.END, history_entry)
self.status_var.set("转换成功")
except Exception as e:
messagebox.showerror("转换错误", f"转换过程中发生错误: {str(e)}")
self.status_var.set(f"错误:{str(e)}")
def display_result(self, input_value, from_unit, result, to_unit):
"""在结果框中显示转换结果"""
self.result_text.config(state=tk.NORMAL)
self.result_text.delete(1.0, tk.END)
# 创建格式化输出
output = f" {input_value} {from_unit}\n= {result:.6f} {to_unit}\n\n"
# 添加科学解释
if "米" in from_unit or "米" in to_unit:
output += "1 米 ≈ 39.37 英寸"
elif "千克" in from_unit or "千克" in to_unit:
output += "1 千克 ≈ 2.20462 磅"
elif "摄氏度" in from_unit or "摄氏度" in to_unit:
output += "水的冰点: 0°C = 32°F\n水的沸点: 100°C = 212°F"
elif "千米/小时" in from_unit or "千米/小时" in to_unit:
output += "1 千米/小时 ≈ 0.621371 英里/小时"
elif "平方米" in from_unit or "平方米" in to_unit:
output += "1 平方米 ≈ 10.7639 平方英尺"
elif "升" in from_unit or "升" in to_unit:
output += "1 升 ≈ 0.264172 加仑"
self.result_text.insert(tk.END, output)
self.result_text.config(state=tk.DISABLED)
def clear_history(self):
"""清除历史记录"""
self.history_listbox.delete(0, tk.END)
self.conversion_history = []
self.status_var.set("历史记录已清除")
# 转换函数
def convert_length(self, value, from_unit, to_unit):
"""长度单位转换"""
# 转换为米
to_meter = {
"米 (m)": 1.0,
"千米 (km)": 1000.0,
"厘米 (cm)": 0.01,
"毫米 (mm)": 0.001,
"英寸 (in)": 0.0254,
"英尺 (ft)": 0.3048,
"码 (yd)": 0.9144,
"英里 (mile)": 1609.344
}
meters = value * to_meter[from_unit]
# 从米转换为目标单位
return meters / to_meter[to_unit]
def convert_mass(self, value, from_unit, to_unit):
"""质量单位转换"""
# 转换为千克
to_kilogram = {
"克 (g)": 0.001,
"千克 (kg)": 1.0,
"毫克 (mg)": 0.000001,
"磅 (lb)": 0.453592,
"盎司 (oz)": 0.0283495,
"吨 (t)": 1000.0
}
kilograms = value * to_kilogram[from_unit]
# 从千克转换为目标单位
return kilograms / to_kilogram[to_unit]
def convert_temperature(self, value, from_unit, to_unit):
"""温度单位转换"""
# 先转换为摄氏度
if from_unit == "摄氏度 (°C)":
celsius = value
elif from_unit == "华氏度 (°F)":
celsius = (value - 32) * 5/9
elif from_unit == "开尔文 (K)":
celsius = value - 273.15
# 从摄氏度转换为目标单位
if to_unit == "摄氏度 (°C)":
return celsius
elif to_unit == "华氏度 (°F)":
return (celsius * 9/5) + 32
elif to_unit == "开尔文 (K)":
return celsius + 273.15
def convert_speed(self, value, from_unit, to_unit):
"""速度单位转换"""
# 转换为米/秒
to_mps = {
"米/秒 (m/s)": 1.0,
"千米/小时 (km/h)": 0.277778,
"英里/小时 (mph)": 0.44704,
"节 (kn)": 0.514444,
"马赫 (Ma)": 340.3 # 在标准大气条件下
}
mps = value * to_mps[from_unit]
# 从米/秒转换为目标单位
return mps / to_mps[to_unit]
def convert_area(self, value, from_unit, to_unit):
"""面积单位转换"""
# 转换为平方米
to_square_meter = {
"平方米 (m²)": 1.0,
"平方千米 (km²)": 1000000.0,
"公顷 (ha)": 10000.0,
"平方英里 (mi²)": 2589988.11,
"英亩 (acre)": 4046.86,
"平方英尺 (ft²)": 0.092903
}
square_meters = value * to_square_meter[from_unit]
# 从平方米转换为目标单位
return square_meters / to_square_meter[to_unit]
def convert_volume(self, value, from_unit, to_unit):
"""体积单位转换"""
# 转换为立方米
to_cubic_meter = {
"立方米 (m³)": 1.0,
"升 (L)": 0.001,
"毫升 (mL)": 0.000001,
"加仑 (gal)": 0.00378541,
"立方英尺 (ft³)": 0.0283168
}
cubic_meters = value * to_cubic_meter[from_unit]
# 从立方米转换为目标单位
return cubic_meters / to_cubic_meter[to_unit]
if __name__ == "__main__":
root = tk.Tk()
app = UnitConverter(root)
root.mainloop()
功能说明
这个单位转换工具具有以下特点:
1. 多种转换类别:
– 长度:米、千米、厘米、毫米、英寸、英尺、码、英里
– 质量:克、千克、毫克、磅、盎司、吨
– 温度:摄氏度、华氏度、开尔文
– 速度:米/秒、千米/小时、英里/小时、节、马赫
– 面积:平方米、平方千米、公顷、平方英里、英亩、平方英尺
– 体积:立方米、升、毫升、加仑、立方英尺
2. 用户友好的界面:
– 直观的类别选择下拉菜单
– 清晰的输入和输出区域
– 单位选择组合框
– 转换结果展示框
– 转换历史记录
3. 附加功能:
– 实时转换历史记录
– 一键清除历史
– 状态栏显示操作状态
– 支持回车键触发转换
– 结果区域显示相关科学知识
4. 错误处理:
– 输入验证(确保输入的是数字)
– 单位选择验证
– 详细的错误提示
使用说明
1. 选择转换类别(默认为长度)
2. 在输入框中输入要转换的数值
3. 选择源单位和目标单位
4. 点击”转换”按钮或按回车键
5. 查看转换结果和相关信息
6. 所有转换记录会自动保存到历史记录区域
运行要求
只需安装Python(3.x版本)即可运行此程序,不需要额外安装其他库。程序使用了Python标准库中的tkinter模块来创建图形界面。
这个工具对于学生、工程师、科学家或任何需要进行单位转换的用户都非常实用,界面简洁直观,功能全面。
© 版权声明
本站资源来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!
THE END