Tkinter 是一个内置的 Python 库,用于创建图形用户界面 (GUI)。它提供了一套用于建立窗口、框架、按钮、文本框和其他GUI元素的工具。
它很容易使用,而且广泛可用,使它成为在Python中构建GUI应用程序的热门选择。它也是高度可定制的,允许开发者创建独特的、具有视觉吸引力的用户界面。
在本教程中,你将使用Tkinter构建一个货币转换器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 Forex、Forex API等,但你要使用Currency Conversion API。
你可以通过使用 requests
模块或其自身的 currencyapi-python
库将该API集成到你的代码中。如前所述,你将在本教程中使用请求模块。
要使用该API,你需要注册一个API密钥。你可以在 https://app.currencyapi.com/register 注册一个免费账户。一旦你注册了,你可以在仪表板页面上找到你的API密钥(用黑色突出显示)。
创建一个 .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_currency
, to_currency
, 和 amount
。 from_currency
和 to_currency
是被转换货币的ISO货币代码,amount
是你要转换的 from_currency
的金额。
该函数向 API_ENDPOINT
URL发送一个GET请求,将 API_KEY
, from_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。下面是这个应用程序的样子:
该设计包括一个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()
方法来创建输入字段。它需要几个参数,包括 width
, justify
, font
, 和 relief
。然后使用place()方法将创建的部件以特定的坐标放在主框架上。
同样地,转换按钮也是用 Button()
方法创建的。它需要几个参数,如 text
, width
, height
, bg
, fg
, font
, 和 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创建一个简单的货币转换器应用程序。我们涵盖了一些主题,如创建框架、标签、输入部件、组合框和按钮。你还创建了一个函数来根据用户的输入转换货币。
有几种方法可以改进这个应用程序。你可以改进用户界面,使其看起来更有吸引力,增加一个保存转换历史的功能,以及更多。
评论留言