使用 Tkinter 在 Python 中创建费用跟踪器应用程序

2025年3月17日 | 40分钟阅读

在接下来的教程中,我们将借助 Tkinter、TkcalendarSQLite 库,开发一个基于图形用户界面(GUI)的费用跟踪器应用程序。这是一个中级项目,通过它我们将学到很多关于数据库和 GUI 及其在现实生活中的实现。

那么,让我们开始吧。

什么是费用跟踪器?

在印度,有很多人靠固定收入生活,他们发现到了月底,钱就不够用了。虽然这个问题可能是由低薪引起的,但通常是由于糟糕的资金管理技巧所致。费用跟踪器,也称为费用管理器资金管理器,是一种桌面应用程序或软件,允许用户准确记录他们的资金流入和流出。

人们往往在不经意间超支,这可能会带来可怕的后果。我们可以借助每日费用跟踪器来记录我们的日常开支。到月底,我们就能清楚地看到资金的流动情况。这是控制开支、使财务状况恢复有序的最佳方法之一。

关于项目

该项目旨在构建一个基于 GUI 的费用跟踪器。为了构建它,我们需要对 Tkinter 库、SQL 语言及其命令有中等程度的知识和理解,并对 Tkinter 库的不同模块和 tkcalendar 库有基本的了解。

项目先决条件

在 Python 中创建 GUI 助手应用程序时,我们需要一些库和模块。这些模块简要描述如下:

  1. Tkinter:tkinter 模块将帮助我们为应用程序提供图形用户界面(GUI)。
  2. Tkcalendar:tkcalendar 模块将帮助我们处理下拉日历。
  3. SQLite:sqlite 模块将允许我们将 Python 脚本连接到 SQL 数据库。
  4. Datetime:datetime 模块将允许处理日期和时间。

由于 Tkinter、DatetimeSQLite 是 Python 中预装的模块,因此无需手动安装。但是,我们只需要安装 Tkcalendar 模块。

可以使用 PIP 安装程序,在命令提示符或终端中键入以下命令来安装 tkcalendar 模块。

语法

安装完成后,我们可以通过创建一个新的 python 程序文件并导入 tkcalendar 模块来验证 tkcalendar 库是否已正确安装。

以下是说明相同内容的代码片段。

文件:verify.py

现在,让我们保存文件并在命令提示符或终端中运行以下命令。

语法

如果程序没有返回任何导入错误,则表示库已成功安装。如果出现任何异常,请尝试重新安装库并考虑查看其官方文档。

现在让我们开始构建项目。

在 Python 中使用 Tkinter 构建费用跟踪器

为了在 Python 中构建费用跟踪器,我们将创建一个空文件夹并将其命名为“Expense Tracker”。在此文件夹中,我们将创建一个名为“main.py”的 Python 程序文件,我们将在其中编写项目的全部代码。

为了更好地理解,我们已将创建 Python 费用跟踪器的完整项目代码分为几个步骤。这些步骤如下所示:

步骤 1:导入必要的模块。

步骤 2:创建数据库并定义函数以操作数据。

步骤 3:连接到数据库并创建应用程序的主窗口。

步骤 4:向窗口添加必要的控件并设置事件触发器。

让我们更详细地了解上述步骤。

导入必要的模块

首先,我们将导入所有必需的模块,包括 tkinter 模块中的所有控件和模块、tkcalendar 库中的 DateEntry 类,以及 datetimesqlite3 模块。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们从 tkinter 模块导入了所有类和模块,以创建 GUI 窗口并向应用程序添加控件。我们还从 tkinter 模块导入了 ttkmessagebox 模块,以添加 ttk 控件并显示任何重要消息。然后我们导入了 datetime 模块以检索当前日期和时间。我们还导入了 sqlite3 模块来维护输入条目的数据库。最后,我们从 tkcalendar 模块的 DateEntry 类导入,以便从下拉日历中插入日期。

创建数据库并定义必要的函数

现在我们已经将所有必要的模块导入到项目中,是时候创建数据库并定义各种函数来实现应用程序中的不同操作了。这些函数包括从数据库中检索数据并在表格中列出它们、查看数据表中的记录、重置输入字段、从数据库中删除选定的记录、从数据库中删除所有记录、向数据库添加新记录、更新数据库中预先存在的记录的详细信息,以及以文本格式显示记录详细信息。

现在让我们详细了解这些函数的实现。

将所有费用从数据库列出到表格中

我们将首先定义一个函数来列出所有费用。此函数将从数据库表中获取记录,并将这些值迭代插入到我们将使用 Tkinter 创建的数据表中。

现在让我们考虑以下代码片段来说明这一点。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 listAllExpenses()。在此函数内部,我们使用了一些全局变量,如 dbconnectordata_table。然后我们使用 delete() 方法删除 Tkinter 表中已存在的数据。然后我们执行 SQL SELECT 语句以从数据库表中检索数据并将其存储在一个变量中。然后我们使用 fetchall() 方法列出表中的数据。然后我们使用 for 循环遍历这些值,并使用 insert() 方法将它们插入到表中。

查看费用信息

我们现在将定义一个函数来显示所选费用的详细信息。此函数将从所选记录的不同列中收集数据,并在数据框中返回值。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 viewExpenseInfo()。我们在此函数内部使用了一些全局变量,如果表中没有选择任何行,则使用 tkintermessagebox 模块的 showerror() 方法返回一个显示错误的消息框。然后我们使用 item() 方法以字典格式收集所选行的数据。然后我们定义了另一个变量,并将收集到的数据中的值存储在一个列表中。最后,我们从列表中检索日期,并在数据输入框的相应输入字段中设置列表数据。

重置数据输入框中的条目

我们现在将定义一个函数来清除用户在数据框输入字段中的条目。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 clearFields()。在此函数中,我们使用了一些全局变量。然后我们定义了一个变量来存储当前日期。最后,我们将输入字段中的值设置回初始值,并从选择中删除指定的项目。

从表中删除所选记录

我们现在将定义一个函数来从表中以及数据库中删除所选记录。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 removeExpense()。在此函数中,我们检查是否选择了任何行,并使用 tkintermessagebox 模块的 showerror() 方法返回一个显示错误的相应消息框。然后我们以字典格式收集所选行的数据,并定义另一个变量来存储收集到的数据中的值。然后我们使用 tkintermessagebox 模块的 askyesnow() 方法显示一个请求确认的消息框。然后我们执行 SQL DELETE 语句来删除所选记录。然后我们调用 listAllExpenses() 函数并返回一个显示成功消息的消息框。

从表中删除所有条目

我们现在将定义一个函数,以从表格和数据库中删除所有条目。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 removeAllExpenses()。在此函数中,我们借助 askyesno() 方法显示了一个请求用户确认的消息框。然后我们使用 delete() 方法从表中删除所有记录。我们还执行了 SQL DELETE 语句来删除数据库表中的所有条目。我们还调用了 clearFields()listAllExpenses() 函数,并使用 messageboxshowinfo() 方法返回一个显示信息的消息框。

向表中添加新记录

我们现在将定义一个函数,向表格和数据库中添加一条新记录。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 addAnotherExpense()。在此函数中,我们使用了一些全局变量。然后,如果任何字段为空,我们使用 messagebox 模块的 showerror() 方法返回一个引发错误的消息框。然后我们执行 SQL INSERT 语句将记录添加到数据库表中。我们调用了 clearFields()listAllExpenses() 函数,并使用 messageboxshowinfo() 方法返回一个显示 SUCCESS 消息的消息框。

编辑所选费用的详细信息

我们现在将定义一个函数来编辑所选费用的详细信息,并在表格和数据库中更新它。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 editExpense()。在此函数内部,我们使用了一些全局变量。然后我们定义了一个嵌套函数 editExistingExpense()。在这个嵌套函数内部,我们再次使用了一些全局变量,并使用 item() 方法将所选记录的数据以字典格式存储。然后我们从收集的数据中分离出值,将它们存储在另一个变量中,并使用 SQL UPDATE 语句更新数据库表中所选记录的详细信息。然后我们调用了 clearFields()listAllExpenses() 函数,并使用 messageboxshowinfo() 方法返回一个显示 SUCCESS 消息的消息框。在嵌套函数之外,我们使用 messageboxshowerror() 方法返回一个消息框,如果未选择任何行则引发错误。然后我们调用了 viewExpenseInfo() 函数,并使用 Button() 控件创建了一个按钮来调用 editExistingExpense() 函数,以在数据库中编辑记录的更新值。最后,我们使用 grid() 方法在主窗口屏幕上设置了按钮的位置。

用文字显示所选记录的详细信息

我们现在将定义一个函数,返回一个用文字显示记录详细信息的消息框。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 selectedExpenseToWords()。在此函数内部,我们使用了一些全局变量,检查是否选择了行,并使用 messageboxshowerror() 方法返回一个引发错误的消息框。然后我们使用 item() 方法以字典格式收集所选行的数据,并定义另一个变量来存储字典中的值。然后我们定义了要显示的消息,并借助 messagebox 模块的 showinfo() 方法在消息框中返回它。

在将费用详情添加到表格前以文字形式显示

我们现在将定义最后一个函数,在将费用详情插入到表格和数据库之前,以文字形式显示它们。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将函数定义为 expenseToWordsBeforeAdding()。在此函数内部,我们使用了一些全局变量。然后,如果任何字段为空,我们会返回一个引发错误的消息框。然后我们定义了要在消息框中显示的消息。然后,使用 messagebox 模块的 askyesno() 方法在一个消息框中打印此消息,请求确认将详细信息插入数据库表。然后我们调用了 addAnotherExpense() 函数,并使用 messageboxshowinfo() 方法返回一个显示信息的消息框。

连接到数据库并创建应用程序的主窗口

现在我们已经定义了所有必要的函数并创建了数据库,是时候将应用程序连接到数据库并创建应用程序的主窗口了。

首先,我们将使用 sqlite3 模块的不同方法将应用程序连接到数据库。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们将 Python 脚本连接到 SQLite 数据库以存储所有信息。为了连接到数据库,我们使用 sqlite3.connect(<databaseName>) 方法创建了一个实例 dbconnector。现在数据库已创建并激活,我们使用 execute()commit() 方法在数据库中执行函数。

因此,我们成功地建立了与数据库的连接。现在我们将使用 tkinter 模块的 Tk() 类创建一个应用程序的主窗口。我们还将为应用程序设置一个标题及其在屏幕上的大小和位置。我们还将配置背景颜色和图标。

文件:main.py

说明

在上面的代码片段中,我们通过将 Tk() 类实例化为 main_win 创建了主窗口。然后我们使用 title() 方法设置窗口的标题。我们还使用 geometry() 方法设置了窗口的大小和位置,并通过将 resizable() 方法的参数值设置为 0 来禁用可调整大小的选项,以获得更好的用户界面。我们借助 config() 方法配置了窗口的背景颜色。最后,我们使用 iconbitmap() 方法设置了窗口的图标。

向窗口添加必要的控件并设置事件触发器

由于应用程序的主窗口已成功创建,我们将向窗口添加所有必要的控件并设置事件触发器。这些控件包括用于构建其他控件的框架、用于显示重要信息的标签、用于插入数据的输入字段以及用于操作输入数据和调用函数的按钮。

现在让我们详细了解这些控件的添加。

添加框架

我们将首先向主窗口添加框架。这些框架将有助于构建其他控件。可以使用 tkinter 模块的 Frame() 控件创建这些框架。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用 Frame() 控件向窗口添加框架。我们还将前两个框架的 master 参数设置为 main_win,表示窗口的左侧和右侧。然后我们将接下来三个框架的 master 参数设置为 frameLeft,表示左框架的较小框架段。然后我们将剩余两个框架的 master 参数设置为 frameRight,表示右框架的较小框架段。我们通过将其设置为 bg 参数的值来配置背景颜色。最后,我们使用 pack() 方法设置这些框架的位置。

现在我们已经向应用程序添加了框架,是时候将剩余的控件(如标签、输入字段、选项菜单、按钮和表格)添加到它们各自的框架中了。

向 frameL1 框架添加控件

我们将首先向第一个框架,即 frameL1,添加一些标签。这些标签将包括应用程序的标题和指示数据输入部分的副标题。我们将使用 Label() 控件来创建所需的标签。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用 Label() 控件来创建所需的标签。然后我们将这些标签的 master 参数设置为 frameL1 框架。我们还指定了要显示的文本、字体样式、背景和前景色。最后,我们使用 pack() 方法设置上述标签的位置。

向 frameL2 框架添加控件

我们现在将向第二个框架,即 frameL2,添加一些控件。这些控件包括用于显示一些信息的标签、输入字段以及用于输入带标签数据的选项菜单。我们将使用 Label() 控件创建标签,使用 Entry() 控件创建输入字段,使用 OptionMenu() 控件创建下拉菜单。我们还将使用 DateEntry() 控件创建一个下拉日历,供用户输入日期。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用 Label() 控件添加了一些标签,要求用户向应用程序输入日期、费用描述、金额、收款人姓名和支付方式。我们将这些标签的 master 参数设置为我们之前定义的框架之一 frameL2。然后我们使用 grid() 方法以网格格式设置这些标签的位置。然后我们实例化了 StringVar() 类以字符串格式检索数据。我们还实例化了 DoubleVar() 类以双精度数据类型检索金额。然后我们使用 DateEntry() 类添加一个下拉日历,用户可以从中选择日期。我们添加了一些输入字段,供用户输入数据,如费用描述、金额和收款人姓名,使用 Entry() 控件并将其 master 参数设置为 frameL2 框架。我们还包括一个下拉菜单,用于选择支付方式,使用 OptionMenu() 控件并将其 master 参数设置为 frameL2 框架。最后,我们再次使用 grid() 方法,以便在主窗口屏幕上以网格格式设置上述控件的位置。

向 frameL3 框架添加控件

我们现在将向第三个框架,即 frameL3,添加一些按钮。这些按钮将允许用户将费用添加到表格中,在添加前将费用转换为文本,以及重置输入。我们将使用 Button() 控件来创建按钮。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用 Button() 控件向应用程序添加了按钮。我们将这些按钮的 master 参数设置为我们之前创建的框架之一 frameL3。我们还将其 command 参数指定为我们之前定义的用于操作数据的不同函数。最后,我们使用 grid() 方法以网格格式设置这些按钮的位置。

向 frameR1 框架添加控件

我们现在将向第四个框架,即 frameR1,添加更多按钮。这些按钮将允许用户查看所选费用的详细信息,编辑所选费用的详细信息,以文字形式显示费用详细信息,从表中删除所选记录,以及从表中删除所有记录。我们将再次使用 Button() 控件来创建按钮。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用 Button() 控件向应用程序添加了按钮。我们将这些按钮的 master 参数设置为我们之前创建的框架之一 frameR1。我们还将其 command 参数指定为我们之前定义的用于操作数据的不同函数。最后,我们使用 grid() 方法以网格格式设置这些按钮的位置。

向 frameR2 框架添加控件

我们现在将向第五个框架,即 frameR2,添加一个表格。此表格将显示数据库中的所有记录。我们将使用 ttk 模块的 Treeview() 控件为数据创建一个表格结构。我们还将借助 Scrollbar() 控件为此结构添加水平和垂直滚动条,以便用户可以自由滚动以访问数据。此外,我们还将添加不同的标题和列,使其看起来像一个表格。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用 ttk 模块的 Treeview() 控件创建了一个表格结构,并将此控件的 master 参数设置为我们之前定义的框架之一 frameR2。我们还为此控件指定了选择模式和列名。之后,我们使用 Scrollbar() 控件为表格创建了两个滚动条,将这些控件的 master 参数设置为我们之前创建的表格结构 data_table。我们还将这些滚动条的方向分别设置为 HORIZONTALVERTICAL。然后我们使用 pack() 方法设置这些滚动条在表格上的位置。我们还使用 config() 方法在表格上配置这些滚动条。之后,我们向表格添加了不同的标题和列。最后,我们使用 place() 方法设置了表格在主窗口屏幕上的位置。

运行应用程序

我们将使用带有 Tk() 类对象的 mainloop() 方法来运行应用程序。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用了带有 Tk() 类的对象 main_winmainloop() 方法来运行应用程序。

因此,项目代码现在已完成。我们将保存此 python 程序文件并在命令提示符或终端中运行以下命令以查看输出。

语法

但在我们看到输出之前,下面显示了“使用 Tkinter 的费用跟踪器应用程序”的完整项目代码。

完整的项目代码

以下是“在 Python 中使用 Tkinter 的费用跟踪器应用程序”的项目代码。

文件:main.py

输出

Expense Tracker Application using Tkinter in Python