如何用Tkinter构建一个货币转换器GUI

如何用Tkinter建立一个货币转换器GUI

Tkinter 是一个内置的 Python 库,用于创建图形用户界面 (GUI)。它提供了一套用于建立窗口、框架、按钮、文本框和其他GUI元素的工具。

它很容易使用,而且广泛可用,使它成为在Python中构建GUI应用程序的热门选择。它也是高度可定制的,允许开发者创建独特的、具有视觉吸引力的用户界面。

在本教程中,你将使用Tkinter构建一个货币转换器GUI应用程序。

下面是你的最终结果的样子:

货币转换器GUI应用程序

你可以在这个资源库中找到该教程的代码。

先决条件

要继续学习本教程并构建应用程序,你应该具备以下条件:

  • 具有Python编程语言的基本知识
  • 在你的系统上安装了Python 3.8以上版本
  • 熟悉Tkinter和Requests库

如何设置你的虚拟环境

在你开始编码之前,你需要确保你安装了所有必要的工具和库。为了确保你有一个干净和隔离的环境,你将使用venv创建一个虚拟环境。

创建一个项目目录并在终端导航到它:

mkdir currency-converter
cd currency-converter

使用以下命令创建一个名为 env 的虚拟环境:

python -m venv env

现在Python带有预装的 venv 库,用于创建虚拟环境。

像这样激活虚拟环境:

source env/bin/activate

注意:如果你在Windows上,你需要使用 source env/Scripts/activate 来激活这个环境。

你应该在你的终端提示中看到 (env) ,表明虚拟环境已经被激活。

如何安装库

现在你已经创建了虚拟环境,你可以安装以下库:

  • requests: 该库帮助你在API端点上发送请求。
  • python-decouple: 该库帮助你读取环境变量的值。
  • pillow: 该库帮助你读取环境变量的值: 该库为你的Python解释器增加了图像处理能力。

要安装这些库,请运行以下命令:

pip install requests python-decouple pillow

如何构建货币转换器的实用功能

在本节中,你将开始构建我们的货币转换器GUI的核心功能。你将创建两个实用函数,用于转换货币和从JSON文件中检索货币代码。

为了定义这些实用功能,你将在项目中创建一个名为 utils.py 的新文件。这个文件将包含你的货币转换器GUI的所有实用函数。

从JSON文件中获取货币代码的实用函数

这个实用函数将从JSON文件中获取货币代码。这个函数将允许你用用户可以选择的可用货币列表来填充GUI。

创建一个 currency.json 文件,包括各种货币的货币代码和名称。该JSON文件有以下结构:

[
{ "AED": "United Arab Emirates Dirham" },
{ "AFN": "Afghan Afghani" },
{ "ALL": "Albanian Lek" },
...
]

你可以从这个链接中获得 currency.json 文件的内容,并将其复制到你的项目中的 currency.json 文件。

添加以下代码来定义第一个实用函数:

import json
def get_currencies() -> list:
currency_codes = []
with open('currency.json') as f:
currency_data = json.load(f)
for currency in currency_data:
code, _ = list(currency.items())[0]
currency_codes.append(code)
return sorted(currency_codes

在上面的代码中,你定义了一个 get_currencies() 函数,用来返回一个货币代码的列表。在该函数中,你创建了一个名为 currency_codes 的空列表,你将用它来存储货币代码。然后,在读取模式下打开 currency.json 文件,使用 json.load() 方法将该文件的内容加载到一个叫做 currency_data 的 Python 字典中。

接下来,使用 for 循环遍历 currency_data 字典中的每个项目。currency_data 字典中的每个项目本身就是一个字典,有一个代表货币代码及其名称的键值对。在 for 循环中,你使用 list() 函数将每种货币的键值对转换为一个列表。

由于每个 dictionary 只包含一个键值对,我们可以使用 items() 方法将 dictionary 转换为包含键值对的元组列表。

然后你使用元组解包,将列表中的第一个元素分配给 code 变量,并使用 _ 忽略第二个元素。

最后,你将代表货币代码的 code 变量追加到 currency_codes 列表中。在循环浏览 currency_data 中的所有货币后,使用 sorted() 函数将 currency_codes 列表按升序排序,并从该函数中返回。

如果你调用该函数并打印其结果,你将得到以下输出:

['ADA', 'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AVAX', 'AWG', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BNB', 'BND', 'BOB', 'BRL', 'BSD', 'BTC', 'BTN', 'BWP', 'BYN', 'BYR', 'BZD', 'CAD', 'CDF', 'CHF', 'CLF', 'CLP', 'CNY', 'COP', 'CRC', 'CUC', 'CUP', 'CVE', 'CZK', 'DJF', 'DKK', 'DOP', 'DOT', 'DZD', 'EGP', 'ERN', 'ETB', 'ETH', 'EUR', 'FJD', 'FKP', 'GBP', 'GEL', 'GGP', 'GHS', 'GIP', 'GMD', 'GNF', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'IMP', 'INR', 'IQD', 'IRR', 'ISK', 'JEP', 'JMD', 'JOD', 'JPY', 'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LTC', 'LTL', 'LVL', 'LYD', 'MAD', 'MATIC', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRO', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZN', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SBD', 'SCR', 'SDG', 'SEK', 'SGD', 'SHP', 'SLL', 'SOL', 'SOS', 'SRD', 'STD', 'SVC', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TOP', 'TRY', 'TTD', 'TWD', 'TZS', 'UAH', 'UGX', 'USD', 'UYU', 'UZS', 'VEF', 'VND', 'VUV', 'WST', 'XAF', 'XAG', 'XAU', 'XCD', 'XDR', 'XOF', 'XPF', 'XRP', 'YER', 'ZAR', 'ZMK', 'ZMW', 'ZWL']

转换货币的实用函数

为了建立货币转换器,你需要一个可以将一种货币转换成另一种货币的实用函数。为此,你将使用一个外部API来获取最新的货币兑换值。虽然有许多货币兑换API可用,如API ForexForex API等,但你要使用Currency Conversion API

你可以通过使用 requests 模块或其自身的 currencyapi-python 库将该API集成到你的代码中。如前所述,你将在本教程中使用请求模块。

要使用该API,你需要注册一个API密钥。你可以在 https://app.currencyapi.com/register 注册一个免费账户。一旦你注册了,你可以在仪表板页面上找到你的API密钥(用黑色突出显示)。

currencyapi网站截图

创建一个 .env 文件并添加以下代码来设置环境变量:

export API_KEY='your-api-key-here'

从仪表板上复制你的API密钥,并在上述文件中替换 your-api-key-here 。然后运行以下命令来设置环境变量:

source .env

然后你在Python代码中使用 python-decouple 库来读取API密钥值。

接下来,在同一个 utils.py 文件中,添加以下代码:

import requests
from decouple import config
API_KEY = config('API_KEY')
API_ENDPOINT = 'https://api.currencyapi.com/v3/latest'
def convert_currency(from_currency: str, to_currency: str, amount: float) -> float:
query_params = {
'apikey': API_KEY,
'base_currency': from_currency,
'currencies': to_currency
}
response = requests.get(API_ENDPOINT, params=query_params)
currency_data = response.json()
exchange_rate = currency_data['data'][to_currency]['value']
exchanged_value = exchange_rate * amount
return exchanged_value

convert_currency 函数需要三个参数:from_currencyto_currency, 和 amount。 from_currency 和 to_currency 是被转换货币的ISO货币代码,amount 是你要转换的 from_currency 的金额。

该函数向 API_ENDPOINT URL发送一个GET请求,将 API_KEYfrom_currency, 和 to_currency 作为查询参数。requests 模块的 requests.get() 函数被用来发送请求,params 参数被用来传递查询参数。

一旦收到响应,我们使用 response 对象的 json() 方法将其转换成 Python 字典。一个成功的响应样本看起来像这样:

{
"meta":{
"last_updated_at":"2023-03-30T23:59:59Z"
},
"data":{
"INR":{
"code":"INR",
"value":82.100841
}
}
}

然后从响应字典中提取汇率,用 amount 和 exchange_rate计算出交换值。最后,你返回交换的值。

如何用Tkinter设计货币转换器的GUI

现在你已经准备好了实用功能,你可以用Tkinter设计GUI。下面是这个应用程序的样子:

设计货币转换器的GUI

该设计包括一个300 X 320尺寸的窗口,有一个顶框和一个主框。顶部框架包含应用程序的图标和标题。主框架包括标签、组合框、输入小部件和货币转换按钮。

让我们一步一步地建立这个应用程序。在项目目录下创建一个 main.py 文件。首先,导入必要的模块和函数,以及定义一些颜色常数。

from tkinter import *
from tkinter import Tk, ttk
from PIL import Image, ImageTk
from utils import convert_currency, get_currencies
# Colors
WHITE_COLOR = "#FFFFFF"
BLACK_COLOR = "#333333"
BLUE_COLOR = "#0000FF"

如何创建窗口

当用Tkinter创建一个GUI应用程序时,第一步是创建一个具有特定大小和标题的窗口。在本例中,窗口的大小应该被设置为300×320,标题应该是 “Currency Converter(货币转换器)”。默认情况下,窗口的背景颜色是白色的,而且它不应该是可调整大小的。下面是代码:

# Window Configuration
window = Tk()
window.geometry("300x320")
window.title("Currency Converter")
window.configure(bg=WHITE_COLOR)
window.resizable(height=FALSE, width=FALSE)

如何创建框架

如前所述,你需要创建两个框架–一个顶部框架和一个主框架。顶层框架将包含应用程序的图标和标题,而主框架将包括基本部件,如标签、输入部件、组合框和转换按钮。下面的代码完成了这个任务:

# Create top and main frames
top_frame = Frame(window, width=300, height=60, bg=BLUE_COLOR)
top_frame.grid(row=0, column=0)
main_frame = Frame(window, width=300, height=260, bg=WHITE_COLOR)
main_frame.grid(row=1, column=0)

这里,Frame() 函数被用来创建两个框架。第一个参数是父窗口(本例中是 window ),然后是框架的宽度、高度和背景颜色。然后,你可以使用 grid() 方法,通过指定框架的行和列的位置,把它们放在窗口中。

你把 top_frame  widget放在网格的第一行和第一列,而把 main_frame widget放在网格的第二行和第一列。

如何在顶部框架中添加Widget

之后,你可以创建属于顶框的小部件。如前所述,顶层框架应该有一个应用程序图标和应用程序标题。你可以从Icons8(或从这里)获得一个图标,并将其保存在你的项目目录下,名称为 icon.png

# Top Frame Widgets
icon_image = Image.open('icon.png')
icon_image = icon_image.resize((40, 40))
icon_image = ImageTk.PhotoImage(icon_image)
app_name_label = Label(top_frame, image=icon_image, compound=LEFT, text="Currency Converter", height=3, padx=13, pady=30, anchor=CENTER, font=('Arial 16 bold'), bg=BLUE_COLOR, fg=WHITE_COLOR)
app_name_label.place(x=0, y=0)

该代码首先使用PIL(Python图像库)模块的 Image 类打开图像文件 icon.png。然后使用 resize() 方法将图像的大小调整为40×40。接下来,它使用 ImageTk 模块的 PhotoImage 类将图像转换为可以在GUI中显示的格式。

下一行创建了一个显示应用程序图标和标题的 Label 小部件。你在顶层框架内创建这个部件。该小组件需要几个参数来配置它的外观。

这些参数包括以下内容:

  • 应用程序图标的 image
  • 要显示的 text(”Currency Converter”)。
  • 标签的 height(设置为3)
  • 左侧和顶部的填充(分别设置为13和30)
  • 标签的锚点(设置为中心)。
  • 字体风格 (Arial 16 bold)
  • 背景颜色 (设置为 BLUE_COLOR)
  • 前景颜色 (设置为 WHITE_COLOR)

最后,我们使用 place() 方法来设置标签在顶部框架中的位置。

如何在主框架中添加小工具

如前所述,主框架将包含基本的小工具。让我们一步一步地创建它们。

下面的代码在 main_frame 框架内创建了一个名为 result_label 的标签小部件。这个标签将显示货币转换的结果。

result_label = Label(main_frame, text=" ", width=15, height=2, pady=7, padx=0, anchor=CENTER, font=('Ivy 16 bold'), bg=WHITE_COLOR, fg=BLACK_COLOR, relief=SOLID)
result_label.place(x=50, y=10)

该标签的文本设置为空字符串(” “),宽度为15,高度为2行,Y轴上的填充物为7像素,X轴上的填充物为0像素。文本将使用 anchor=CENTER 选项居中,使用的字体是 Ivy 16 bold。标签的背景颜色被设置为白色(bg=WHITE_COLOR),文本颜色为黑色(fg=BLACK_COLOR)。relief 选项被设置为SOLID,以使标签具有边界。最后,使用 place() 方法将标签放在坐标(50, 10)处。

接下来,在应用程序的设计中,有两个标签–“From “和 “To”,每个标签的下面都有一个 ComboBox

from_label = Label(main_frame, text="From", width=8, height=1, pady=0, padx=0, anchor=NW, font=('Ivy 10 bold'), bg=WHITE_COLOR, fg=BLACK_COLOR, relief=FLAT)
from_label.place(x=48, y=90)
from_combo = ttk.Combobox(main_frame, width=8, justify=CENTER, font=('Ivy 12 bold'),)
from_combo['values'] = (get_currencies())
from_combo.current(0)
from_combo.place(x=50, y=115)
to_label = Label(main_frame, text="To", width=8, height=1, pady=0, padx=0, anchor=NW, font=('Ivy 10 bold'), bg=WHITE_COLOR, fg=BLACK_COLOR, relief=FLAT)
to_label.place(x=158, y=90)
to_combo = ttk.Combobox(main_frame, width=8, justify=CENTER, font=('Ivy 12 bold'),)
to_combo['values'] = (get_currencies())
to_combo.current(1)
to_combo.place(x=160, y=115)

第一个 Label 和 ComboBox 是用来转换货币的。你使用 Label() 函数创建标签,并指定文本、宽度、高度、填充、字体和颜色设置。然后使用place()函数将Label放置在主框架的指定坐标处。

然后使用 ttk.Combobox() 函数创建一个 ComboBox,并指定宽度、字体和对齐方式。使用 get_currencies() 函数(从 utils.py 导入)设置 ComboBox 的可用值,使用 current() 函数将默认值设置为列表中的第一个项目。使用 place() 函数,ComboBox 也被放置在主框架的指定坐标处。

第二个Label和ComboBox是用来转换货币的。Label和ComboBox的创建和放置方式与第一个Label和ComboBox类似,唯一的区别是文本和放置坐标。

应用程序设计中的最后两个部件是输入字段和转换按钮。你可以使用 Entry() 方法来创建输入字段。它需要几个参数,包括 widthjustifyfont, 和 relief。然后使用place()方法将创建的部件以特定的坐标放在主框架上。

同样地,转换按钮也是用 Button() 方法创建的。它需要几个参数,如 textwidthheightbgfgfont, 和 command。然后使用 place() 方法将创建的按钮放在主框架的特定坐标上。

下面是创建输入栏和转换按钮的代码:

amount_entry = Entry(main_frame, width=22, justify=CENTER,
font=('Ivy 12 bold'), relief=SOLID)
amount_entry.place(x=50, y=155)
convert_button = Button(main_frame, text="Convert", width=19, padx=5,
height=1, bg=BLUE_COLOR, fg=WHITE_COLOR, font=('Ivy 12 bold'), command=convert)
convert_button.place(x=50, y=210)

convert_button 部件中的 command 参数需要一个函数名称。在这种情况下,它被设置为 convert。但是 convert 函数还没有被定义。要定义它,你可以在窗口被定义之前添加以下代码:

def convert():
amount = float(amount_entry.get())
from_currency = from_combo.get()
to_currency = to_combo.get()
converted_amount = convert_currency(from_currency, to_currency, amount)
result_label['text'] = f'{to_currency} {converted_amount:.2f}'

convert 函数从 amount_entry 部件中获取用户输入,从 from_combo 和 to_combo 部件中获取选定的货币,并将它们传递给 convert_currency 函数(从 utils.py) 中导入)以获得转换后的金额。然后,它将 text 的值设置为 result_label 部件中的兑换值。

最后,你在文件的最后调用 mainloop() 方法。该方法负责运行应用程序,不断检查用户事件,如鼠标点击、键盘输入和窗口大小的调整,并在必要时更新窗口。

一旦 mainloop() 方法被调用,程序就进入事件循环,开始等待用户事件。窗口将保持开放和活跃,直到用户关闭窗口或程序被终止。

# Mainloop
window.mainloop()

最终代码

这里是你一直在构建的货币转换器GUI应用程序的最终代码。这段代码包含了我们到目前为止讨论过的所有不同的组件,包括创建框架、标签、组合框、输入字段和按钮。

from tkinter import *
from tkinter import Tk, ttk
from PIL import Image, ImageTk
from utils import convert_currency, get_currencies
# Colors
WHITE_COLOR = "#FFFFFF"
BLACK_COLOR = "#333333"
BLUE_COLOR = "#0000FF"
def convert():
amount = float(amount_entry.get())
from_currency = from_combo.get()
to_currency = to_combo.get()
converted_amount = convert_currency(from_currency, to_currency, amount)
result_label['text'] = f'{to_currency} {converted_amount:.2f}'
# Window Configuration
window = Tk()
window.geometry("300x320")
window.title("Currency Converter")
window.configure(bg=WHITE_COLOR)
window.resizable(height=FALSE, width=FALSE)
# Frames
top_frame = Frame(window, width=300, height=60, bg=BLUE_COLOR)
top_frame.grid(row=0, column=0)
main_frame = Frame(window, width=300, height=260, bg=WHITE_COLOR)
main_frame.grid(row=1, column=0)
# Top Frame Widgets
icon_image = Image.open('icon.png')
icon_image = icon_image.resize((40, 40))
icon_image = ImageTk.PhotoImage(icon_image)
app_name_label = Label(top_frame, image=icon_image, compound=LEFT, text="Currency Converter", height=3, padx=13, pady=30, anchor=CENTER, font=('Arial 16 bold'), bg=BLUE_COLOR, fg=WHITE_COLOR)
app_name_label.place(x=0, y=0)
# Main Frame Widgets
result_label = Label(main_frame, text=" ", width=15, height=2, pady=7, padx=0, anchor=CENTER, font=('Ivy 16 bold'), bg=WHITE_COLOR, fg=BLACK_COLOR, relief=SOLID)
result_label.place(x=50, y=10)
from_label = Label(main_frame, text="From", width=8, height=1, pady=0, padx=0, anchor=NW, font=('Ivy 10 bold'), bg=WHITE_COLOR, fg=BLACK_COLOR, relief=FLAT)
from_label.place(x=48, y=90)
from_combo = ttk.Combobox(main_frame, width=8, justify=CENTER, font=('Ivy 12 bold'),)
from_combo['values'] = (get_currencies())
from_combo.current(0)
from_combo.place(x=50, y=115)
to_label = Label(main_frame, text="To", width=8, height=1, pady=0, padx=0, anchor=NW, font=('Ivy 10 bold'), bg=WHITE_COLOR, fg=BLACK_COLOR, relief=FLAT)
to_label.place(x=158, y=90)
to_combo = ttk.Combobox(main_frame, width=8, justify=CENTER, font=('Ivy 12 bold'),)
to_combo['values'] = (get_currencies())
to_combo.current(1)
to_combo.place(x=160, y=115)
amount_entry = Entry(main_frame, width=22, justify=CENTER,
font=('Ivy 12 bold'), relief=SOLID)
amount_entry.place(x=50, y=155)
convert_button = Button(main_frame, text="Convert", width=19, padx=5,
height=1, bg=BLUE_COLOR, fg=WHITE_COLOR, font=('Ivy 12 bold'), command=convert)
convert_button.place(x=50, y=210)
# Mainloop
window.mainloop()

你终于可以运行应用程序并开始转换货币了!

小结

在本教程中,你学会了如何使用Python和Tkinter创建一个简单的货币转换器应用程序。我们涵盖了一些主题,如创建框架、标签、输入部件、组合框和按钮。你还创建了一个函数来根据用户的输入转换货币。

有几种方法可以改进这个应用程序。你可以改进用户界面,使其看起来更有吸引力,增加一个保存转换历史的功能,以及更多。

评论留言