当前位置:   article > 正文

第四篇【传奇开心果系列】beeware的Toga开发移动应用示例:健身追踪应用

第四篇【传奇开心果系列】beeware的Toga开发移动应用示例:健身追踪应用

传奇开心果博文系列

  • 系列博文目录
    • beeware的Toga开发移动应用示例系列
  • 博文目录
    • 前言
    • 一、记录存储运动活动数据
    • 二、添加添加统计显示功能
    • 三、添加图表显示数据分析功能
    • 四、增加健身计划管理
    • 五、增加备份数据恢复数据功能
    • 六、初步整合代码示例
    • 七、增加登录验证功能
    • 八、完成最终整合的小项目示例代码

系列博文目录

beeware的Toga开发移动应用示例系列

博文目录

前言

健身追踪应用:使用 Beeware的toga集成库和sqlite3嵌入式数据库开发人员可以开发健康和健身应用程序,如健康追踪应用、锻炼计划应用等。通过与移动设备的传感器和健康数据接口进行交互,可以实现数据收集、分析和展示等功能。
在这里插入图片描述

一、记录存储运动活动数据

在这里插入图片描述下面是使用beeware的toga和SQLite3实现健身追踪应用的示例代码:


import toga

from toga.style import Pack

from toga.style.pack import COLUMN, ROW

import sqlite3

class FitnessApp(toga.App):

def startup(self):

self.db_conn = sqlite3.connect('fitness_tracker.db')

self.create_table()

self.main_window = toga.MainWindow(title=self.name)

self.main_window.content = self.build_main_box()

self.main_window.show()

def create_table(self):

cursor = self.db_conn.cursor()

cursor.execute('''

CREATE TABLE IF NOT EXISTS activities (

id INTEGER PRIMARY KEY AUTOINCREMENT,

activity_type TEXT,

time TEXT,

distance REAL,

calories REAL

)

''')

self.db_conn.commit()

def add_activity(self, widget):

activity_type = self.activity_type.value

time = self.time.value

distance = float(self.distance.value)

calories = float(self.calories.value)

cursor = self.db_conn.cursor()

cursor.execute('''

INSERT INTO activities (activity_type, time, distance, calories)

VALUES (?, ?, ?, ?)

''', (activity_type, time, distance, calories))

self.db_conn.commit()

self.activity_type.value = ''

self.time.value = ''

self.distance.value = ''

self.calories.value = ''

def build_main_box(self):

activity_label = toga.Label('运动类型:', style=Pack(padding=(0, 5)))

self.activity_type = toga.TextInput(style=Pack(flex=1))

time_label = toga.Label('时间:', style=Pack(padding=(0, 5)))

self.time = toga.TextInput(style=Pack(flex=1))

distance_label = toga.Label('距离:', style=Pack(padding=(0, 5)))

self.distance = toga.TextInput(style=Pack(flex=1))

calories_label = toga.Label('消耗卡路里:', style=Pack(padding=(0, 5)))

self.calories = toga.TextInput(style=Pack(flex=1))

add_button = toga.Button('添加运动', on_press=self.add_activity, style=Pack(padding=5))

activity_box = toga.Box(children=[activity_label, self.activity_type], style=Pack(direction=ROW, padding=5))

time_box = toga.Box(children=[time_label, self.time], style=Pack(direction=ROW, padding=5))

distance_box = toga.Box(children=[distance_label, self.distance], style=Pack(direction=ROW, padding=5))

calories_box = toga.Box(children=[calories_label, self.calories], style=Pack(direction=ROW, padding=5))

main_box = toga.Box(

children=[activity_box, time_box, distance_box, calories_box, add_button],

style=Pack(direction=COLUMN, padding=10)

)

return main_box

def main():

return FitnessApp('健身追踪应用', 'com.example.fitnessapp')

if __name__ == '__main__':

main().main_loop()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123

以上代码是一个简单的健身追踪应用示例,使用了beeware的Toga作为GUI库,sqlite3作为数据库存储运动记录。用户可以通过界面输入运动类型、时间、距离和消耗的卡路里,并点击"添加运动"按钮将数据保存到SQLite数据库中。
在这里插入图片描述

二、添加添加统计显示功能

要为健身追踪应用添加统计数据分析功能,你可以修改示例代码,添加相应的功能和界面元素。下面是一个简单的示例,展示如何计算每周、每月和每年的运动时长和消耗的卡路里,并在界面上显示统计信息:


import datetime

import calendar

class FitnessApp(toga.App):

# ...

def calculate_weekly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE time >= ? AND time <= ?

''', (self.get_start_of_week(), self.get_end_of_week()))

result = cursor.fetchone()

return result[0], result[1]

def calculate_monthly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE time >= ? AND time <= ?

''', (self.get_start_of_month(), self.get_end_of_month()))

result = cursor.fetchone()

return result[0], result[1]

def calculate_yearly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE time >= ? AND time <= ?

''', (self.get_start_of_year(), self.get_end_of_year()))

result = cursor.fetchone()

return result[0], result[1]

def get_start_of_week(self):

today = datetime.date.today()

start_of_week = today - datetime.timedelta(days=today.weekday())

return start_of_week.isoformat()

def get_end_of_week(self):

today = datetime.date.today()

end_of_week = today + datetime.timedelta(days=6 - today.weekday())

return end_of_week.isoformat()

def get_start_of_month(self):

today = datetime.date.today()

start_of_month = today.replace(day=1)

return start_of_month.isoformat()

def get_end_of_month(self):

today = datetime.date.today()

_, last_day = calendar.monthrange(today.year, today.month)

end_of_month = today.replace(day=last_day)

return end_of_month.isoformat()

def get_start_of_year(self):

today = datetime.date.today()

start_of_year = today.replace(month=1, day=1)

return start_of_year.isoformat()

def get_end_of_year(self):

today = datetime.date.today()

end_of_year = today.replace(month=12, day=31)

return end_of_year.isoformat()

def build_stats_box(self):

weekly_label = toga.Label('每周统计:', style=Pack(padding=(0, 5)))

weekly_time, weekly_calories = self.calculate_weekly_stats()

weekly_stats = toga.Label(f'运动时长: {weekly_time} 小时, 消耗卡路里: {weekly_calories}', style=Pack(padding=(0, 5)))

monthly_label = toga.Label('每月统计:', style=Pack(padding=(0, 5)))

monthly_time, monthly_calories = self.calculate_monthly_stats()

monthly_stats = toga.Label(f'运动时长: {monthly_time} 小时, 消耗卡路里: {monthly_calories}', style=Pack(padding=(0, 5)))

yearly_label = toga.Label('每年统计:', style=Pack(padding=(0, 5)))

yearly_time, yearly_calories = self.calculate_yearly_stats()

yearly_stats = toga.Label(f'运动时长: {yearly_time} 小时, 消耗卡路里: {yearly_calories}', style=Pack(padding=(0, 5)))

stats_box = toga.Box(

children=[weekly_label, weekly_stats, monthly_label, monthly_stats, yearly_label, yearly_stats],

style=Pack(direction=COLUMN, padding=10)

)

return stats_box

def build_main_box(self):

# ...

stats_box = self.build_stats_box()

main_box = toga.Box(

children=[activity_box, time_box, distance_box, calories_box, add_button, stats_box],

style=Pack(direction=COLUMN, padding=10)

)

return main_box

# ...

def main():

return FitnessApp('健身追踪应用', 'com.example.fitnessapp')

if __name__ == '__main__':

main().main_loop()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169

在上述示例中,我们添加了calculate_weekly_stats()calculate_monthly_stats()calculate_yearly_stats()方法来计算每周、每月和每年的运动时长和消耗的卡路里。然后,在build_stats_box()方法中,我们创建了显示统计信息的标签,并将其添加到界面中的stats_box中。最后,将stats_box添加到主界面的布局中。

这样,用户就可以在健身追踪应用中查看每周、每月和每年的运动统计信息了。
在这里插入图片描述

三、添加图表显示数据分析功能

要为健身追踪应用添加数据分析功能,你可以使用Python的数据分析库(如pandas和matplotlib)来处理和可视化运动数据。下面是一个示例代码,展示如何使用pandas和matplotlib对健身数据进行分析和绘图:


import pandas as pd

import matplotlib.pyplot as plt

class FitnessApp(toga.App):

# ...

def analyze_data(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT activity_type, SUM(time) as total_time, SUM(calories) as total_calories

FROM activities

GROUP BY activity_type

''')

result = cursor.fetchall()

data = pd.DataFrame(result, columns=['Activity Type', 'Total Time', 'Total Calories'])



# 绘制柱状图

data.plot(x='Activity Type', y='Total Time', kind='bar', legend=False)

plt.title('Total Time Spent on Each Activity')

plt.xlabel('Activity Type')

plt.ylabel('Total Time (hours)')

plt.show()

# 绘制饼图

data.plot(x='Activity Type', y='Total Calories', kind='pie', labels=data['Activity Type'], autopct='%1.1f%%')

plt.title('Total Calories Burned for Each Activity')

plt.ylabel('')

plt.show()

def build_main_box(self):

# ...

analyze_button = toga.Button('数据分析', on_press=self.analyze_data, style=Pack(padding=5))

# ...

main_box = toga.Box(

children=[activity_box, time_box, distance_box, calories_box, add_button, analyze_button, stats_box],

style=Pack(direction=COLUMN, padding=10)

)

return main_box

# ...

def main():

return FitnessApp('健身追踪应用', 'com.example.fitnessapp')

if __name__ == '__main__':

main().main_loop()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

在上述示例中,我们添加了analyze_data()方法来从数据库中获取运动数据,并使用pandas创建一个DataFrame对象。然后,我们使用matplotlib库来绘制柱状图和饼图,展示每种运动类型的总时长和总消耗卡路里。

build_main_box()方法中,我们创建了一个"数据分析"按钮,并将其添加到主界面的布局中。当用户点击该按钮时,analyze_data()方法会被调用,进行数据分析和绘图操作。
在这里插入图片描述

四、增加健身计划管理

要为健身追踪应用添加健身计划管理功能,你可以修改示例代码,添加相应的功能和界面元素。下面是一个简单的示例,展示如何创建、查看和管理健身计划:


class FitnessApp(toga.App):

# ...

def create_plan(self, widget):

plan_name = self.plan_name.value

plan_description = self.plan_description.value

cursor = self.db_conn.cursor()

cursor.execute('''

INSERT INTO plans (name, description)

VALUES (?, ?)

''', (plan_name, plan_description))

self.db_conn.commit()

self.plan_name.value = ''

self.plan_description.value = ''

def view_plans(self, widget):

cursor = self.db_conn.cursor()

cursor.execute('SELECT name, description FROM plans')

plans = cursor.fetchall()

plan_list = toga.Table(

headings=['计划名称', '计划描述'],

data=plans,

style=Pack(flex=1)

)

self.plan_window = toga.Window(title='健身计划列表')

self.plan_window.content = plan_list

self.plan_window.show()

def build_main_box(self):

# ...

plan_name_label = toga.Label('计划名称:', style=Pack(padding=(0, 5)))

self.plan_name = toga.TextInput(style=Pack(flex=1))

plan_description_label = toga.Label('计划描述:', style=Pack(padding=(0, 5)))

self.plan_description = toga.TextInput(style=Pack(flex=1))

create_plan_button = toga.Button('创建计划', on_press=self.create_plan, style=Pack(padding=5))

view_plans_button = toga.Button('查看计划', on_press=self.view_plans, style=Pack(padding=5))

plan_box = toga.Box(

children=[plan_name_label, self.plan_name, plan_description_label, self.plan_description],

style=Pack(direction=COLUMN, padding=10)

)

main_box = toga.Box(

children=[activity_box, time_box, distance_box, calories_box, add_button, plan_box,

create_plan_button, view_plans_button, stats_box],

style=Pack(direction=COLUMN, padding=10)

)

return main_box

# ...

def main():

return FitnessApp('健身追踪应用', 'com.example.fitnessapp')

if __name__ == '__main__':

main().main_loop()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

在上述示例中,我们添加了create_plan()方法来创建健身计划,并将计划名称和描述保存到数据库中。我们还添加了view_plans()方法来查看已创建的健身计划,并在一个新的窗口中显示计划列表。

build_main_box()方法中,我们创建了输入计划名称和描述的文本框,以及"创建计划"和"查看计划"按钮。当用户点击"创建计划"按钮时,create_plan()方法会被调用,创建并保存健身计划。当用户点击"查看计划"按钮时,view_plans()方法会被调用,显示健身计划列表。
在这里插入图片描述

五、增加备份数据恢复数据功能

要为健身追踪应用添加备份和恢复数据功能,你可以使用文件操作来实现。下面是一个简单的示例代码,展示如何实现数据的备份和恢复功能:


import shutil

class FitnessApp(toga.App):

# ...

def backup_data(self, widget):

# 关闭数据库连接

self.db_conn.close()

# 备份数据库文件

shutil.copy2('fitness_tracker.db', 'backup/fitness_tracker_backup.db')

# 重新打开数据库连接

self.db_conn = sqlite3.connect('fitness_tracker.db')

# 提示备份成功

toga.dialog.info('备份成功', '数据已成功备份至 backup 文件夹。')

def restore_data(self, widget):

# 关闭数据库连接

self.db_conn.close()

# 恢复数据库文件

shutil.copy2('backup/fitness_tracker_backup.db', 'fitness_tracker.db')

# 重新打开数据库连接

self.db_conn = sqlite3.connect('fitness_tracker.db')

# 提示恢复成功

toga.dialog.info('恢复成功', '数据已成功恢复。')

def build_main_box(self):

# ...

backup_button = toga.Button('备份数据', on_press=self.backup_data, style=Pack(padding=5))

restore_button = toga.Button('恢复数据', on_press=self.restore_data, style=Pack(padding=5))

main_box = toga.Box(

children=[activity_box, time_box, distance_box, calories_box, add_button, plan_box,

create_plan_button, view_plans_button, stats_box, backup_button, restore_button],

style=Pack(direction=COLUMN, padding=10)

)

return main_box

# ...

def main():

return FitnessApp('健身追踪应用', 'com.example.fitnessapp')

if __name__ == '__main__':

main().main_loop()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

在上述示例中,我们添加了backup_data()方法来备份数据库文件。该方法关闭数据库连接,将数据库文件复制到指定的备份文件夹中,然后重新打开数据库连接。

我们还添加了restore_data()方法来恢复数据库文件。该方法关闭数据库连接,将备份文件复制回原始的数据库文件位置,然后重新打开数据库连接。

build_main_box()方法中,我们创建了"备份数据"和"恢复数据"按钮,并将其添加到主界面的布局中。当用户点击"备份数据"按钮时,backup_data()方法会被调用,执行数据备份操作。当用户点击"恢复数据"按钮时,restore_data()方法会被调用,执行数据恢复操作。

请确保在进行数据备份和恢复操作时,谨慎处理用户数据,以免丢失或覆盖重要数据。
在这里插入图片描述

六、初步整合代码示例


import toga

from toga.style import Pack

from toga.style.pack import COLUMN, ROW

import sqlite3

import datetime

import calendar

import pandas as pd

import matplotlib.pyplot as plt

import shutil

class FitnessApp(toga.App):

def startup(self):

self.db_conn = sqlite3.connect('fitness_tracker.db')

self.create_table()

self.main_window = toga.MainWindow(title=self.name)

self.main_window.content = self.build_main_box()

self.main_window.show()

def create_table(self):

cursor = self.db_conn.cursor()

cursor.execute('''

CREATE TABLE IF NOT EXISTS activities (

id INTEGER PRIMARY KEY AUTOINCREMENT,

activity_type TEXT,

time TEXT,

distance REAL,

calories REAL

)

''')

cursor.execute('''

CREATE TABLE IF NOT EXISTS plans (

id INTEGER PRIMARY KEY AUTOINCREMENT,

name TEXT,

description TEXT

)

''')

self.db_conn.commit()

def add_activity(self, widget):

activity_type = self.activity_type.value

time = self.time.value

distance = float(self.distance.value)

calories = float(self.calories.value)

cursor = self.db_conn.cursor()

cursor.execute('''

INSERT INTO activities (activity_type, time, distance, calories)

VALUES (?, ?, ?, ?)

''', (activity_type, time, distance, calories))

self.db_conn.commit()

self.activity_type.value = ''

self.time.value = ''

self.distance.value = ''

self.calories.value = ''

def calculate_weekly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE time >= ? AND time <= ?

''', (self.get_start_of_week(), self.get_end_of_week()))

result = cursor.fetchone()

return result[0], result[1]

def calculate_monthly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE time >= ? AND time <= ?

''', (self.get_start_of_month(), self.get_end_of_month()))

result = cursor.fetchone()

return result[0], result[1]

def calculate_yearly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE time >= ? AND time <= ?

''', (self.get_start_of_year(), self.get_end_of_year()))

result = cursor.fetchone()

return result[0], result[1]

def get_start_of_week(self):

today = datetime.date.today()

start_of_week = today - datetime.timedelta(days=today.weekday())

return start_of_week.isoformat()

def get_end_of_week(self):

today = datetime.date.today()

end_of_week = today + datetime.timedelta(days=6 - today.weekday())

return end_of_week.isoformat()

def get_start_of_month(self):

today = datetime.date.today()

start_of_month = today.replace(day=1)

return start_of_month.isoformat()

def get_end_of_month(self):

today = datetime.date.today()

_, last_day = calendar.monthrange(today.year, today.month)

end_of_month = today.replace(day=last_day)

return end_of_month.isoformat()

def get_start_of_year(self):

today = datetime.date.today()

start_of_year = today.replace(month=1, day=1)

return start_of_year.isoformat()

def get_end_of_year(self):

today = datetime.date.today()

end_of_year = today.replace(month=12, day=31)

return end_of_year.isoformat()

def analyze_data(self, widget):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT activity_type, SUM(time) as total_time, SUM(calories) as total_calories

FROM activities

GROUP BY activity_type

''')

result = cursor.fetchall()

data = pd.DataFrame(result, columns=['Activity Type', 'Total Time', 'Total Calories'])



# 绘制柱状图

data.plot(x='Activity Type', y='Total Time', kind='bar', legend=False)

plt.title('Total Time Spent on Each Activity')

plt.xlabel('Activity Type')

plt.ylabel('Total Time (hours)')

plt.show()

# 绘制饼图

data.plot(x='Activity Type', y='Total Calories', kind='pie', labels=data['Activity Type'], autopct='%1.1f%%')

plt.title('Total Calories Burned for Each Activity')

plt.ylabel('')

plt.show()

def create_plan(self, widget):

plan_name = self.plan_name.value

plan_description = self.plan_description.value

cursor = self.db_conn.cursor()

cursor.execute('''

INSERT INTO plans (name, description)

VALUES (?, ?)

''', (plan_name, plan_description))

self.db_conn.commit()

self.plan_name.value = ''

self.plan_description.value = ''

def view_plans(self, widget):

cursor = self.db_conn.cursor()

cursor.execute('SELECT name, description FROM plans')

plans = cursor.fetchall()

plan_list = toga.Table(

headings=['计划名称', '计划描述'],

data=plans,

style=Pack(flex=1)

)

self.plan_window = toga.Window(title='健身计划列表')

self.plan_window.content = plan_list

self.plan_window.show()

def backup_data(self, widget):

self.db_conn.close()

shutil.copy2('fitness_tracker.db', 'backup/fitness_tracker_backup.db')

self.db_conn = sqlite3.connect('fitness_tracker.db')

toga.dialog.info('备份成功', '数据已成功备份至 backup 文件夹。')

def restore_data(self, widget):

self.db_conn.close()

shutil.copy2('backup/fitness_tracker_backup.db', 'fitness_tracker.db')

self.db_conn = sqlite3.connect('fitness_tracker.db')

toga.dialog.info('恢复成功', '数据已成功恢复。')

def build_main_box(self):

activity_label = toga.Label('运动类型:', style=Pack(padding=(0, 5)))

self.activity_type = toga.TextInput(style=Pack(flex=1))

time_label = toga.Label('时间:', style=Pack(padding=(0, 5)))

self.time = toga.TextInput(style=Pack(flex=1))

distance_label = toga.Label('距离:', style=Pack(padding=(0, 5)))

self.distance = toga.TextInput(style=Pack(flex=1))

calories_label = toga.Label('消耗卡路里:', style=Pack(padding=(0, 5)))

self.calories = toga.TextInput(style=Pack(flex=1))

add_button = toga.Button('添加运动', on_press=self.add_activity, style=Pack(padding=5))

analyze_button = toga.Button('数据分析', on_press=self.analyze_data, style=Pack(padding=5))

plan_name_label = toga.Label('计划名称:', style=Pack(padding=(0, 5)))

self.plan_name = toga.TextInput(style=Pack(flex=1))

plan_description_label = toga.Label('计划描述:', style=Pack(padding=(0, 5)))

self.plan_description = toga.TextInput(style=Pack(flex=1))

create_plan_button = toga.Button('创建计划', on_press=self.create_plan, style=Pack(padding=5))

view_plans_button = toga.Button('查看计划', on_press=self.view_plans, style=Pack(padding=5))

main_box = toga.Box(

children=[

activity_label, self.activity_type, time_label, self.time,

distance_label, self.distance, calories_label, self.calories,

add_button, analyze_button,

plan_name_label, self.plan_name, plan_description_label, self.plan_description,

create_plan_button, view_plans_button

],

style=Pack(direction=COLUMN, padding=10)

)

return main_box

def main():

return FitnessApp('健身追踪应用', 'com.example.fitnessapp')

if __name__ == '__main__':

main().main_loop()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377

上述代码是一个比较完整的健身追踪应用示例,包括记录运动数据、统计分析、健身计划管理以及数据备份和恢复功能。你可以根据需要进行修改和扩展,以满足实际需求。
在这里插入图片描述

七、增加登录验证功能

要为健身追踪应用添加登录验证功能,你可以使用用户名和密码进行身份验证。下面是一个示例代码,展示如何实现登录验证功能:


import toga

from toga.style import Pack

from toga.style.pack import COLUMN, ROW

import sqlite3

class FitnessApp(toga.App):

def startup(self):

self.db_conn = sqlite3.connect('fitness_tracker.db')

self.create_table()

self.login_window = toga.MainWindow(title='登录')

self.login_window.content = self.build_login_box()

self.login_window.show()

def create_table(self):

cursor = self.db_conn.cursor()

cursor.execute('''

CREATE TABLE IF NOT EXISTS users (

id INTEGER PRIMARY KEY AUTOINCREMENT,

username TEXT UNIQUE,

password TEXT

)

''')

self.db_conn.commit()

def build_login_box(self):

username_label = toga.Label('用户名:', style=Pack(padding=(0, 5)))

self.username_input = toga.TextInput(style=Pack(flex=1))

password_label = toga.Label('密码:', style=Pack(padding=(0, 5)))

self.password_input = toga.PasswordInput(style=Pack(flex=1))

login_button = toga.Button('登录', on_press=self.login, style=Pack(padding=5))

login_box = toga.Box(

children=[

username_label, self.username_input,

password_label, self.password_input,

login_button

],

style=Pack(direction=COLUMN, padding=10)

)

return login_box

def login(self, widget):

username = self.username_input.value

password = self.password_input.value

cursor = self.db_conn.cursor()

cursor.execute('SELECT * FROM users WHERE username=? AND password=?', (username, password))

user = cursor.fetchone()

if user is not None:

self.username_input.value = ''

self.password_input.value = ''

self.login_window.close()

self.show_main_window()

else:

toga.dialog.info('登录失败', '用户名或密码错误。')

def show_main_window(self):

self.main_window = toga.MainWindow(title=self.name)

self.main_window.content = self.build_main_box()

self.main_window.show()

def build_main_box(self):

# ... 剩余的代码和界面元素

def main():

return FitnessApp('健身追踪应用', 'com.example.fitnessapp')

if __name__ == '__main__':

main().main_loop()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119

在上述代码中,我们添加了一个users表来存储用户的用户名和密码。在build_login_box()方法中,我们创建了用户名和密码输入框以及登录按钮,并在login()方法中实现了登录验证逻辑。当用户点击登录按钮时,会检查输入的用户名和密码是否与数据库中的用户匹配。如果匹配成功,就关闭登录窗口并显示主窗口;如果匹配失败,则显示登录失败的提示。

startup()方法中,我们首先创建了用户表,并显示登录窗口。只有在成功登录后,才会显示主窗口。

请注意,这只是一个简单的示例,你可能需要根据实际需求进一步优化代码和添加更多的安全性措施,例如使用哈希算法对密码进行加密存储。同时,建议在生产环境中使用专业的身份验证解决方案,确保应用的安全性。
在这里插入图片描述

八、完成最终整合的小项目示例代码


import toga

from toga.style import Pack

from toga.style.pack import COLUMN, ROW

import sqlite3

import datetime

import calendar

import pandas as pd

import matplotlib.pyplot as plt

import shutil

class FitnessApp(toga.App):

def startup(self):

self.db_conn = sqlite3.connect('fitness_tracker.db')

self.create_table()

self.login_window = toga.MainWindow(title='登录')

self.login_window.content = self.build_login_box()

self.login_window.show()

def create_table(self):

cursor = self.db_conn.cursor()

cursor.execute('''

CREATE TABLE IF NOT EXISTS users (

id INTEGER PRIMARY KEY AUTOINCREMENT,

username TEXT UNIQUE,

password TEXT

)

''')

cursor.execute('''

CREATE TABLE IF NOT EXISTS activities (

id INTEGER PRIMARY KEY AUTOINCREMENT,

user_id INTEGER,

activity_type TEXT,

time TEXT,

distance REAL,

calories REAL

)

''')

cursor.execute('''

CREATE TABLE IF NOT EXISTS plans (

id INTEGER PRIMARY KEY AUTOINCREMENT,

user_id INTEGER,

name TEXT,

description TEXT

)

''')

self.db_conn.commit()

def build_login_box(self):

username_label = toga.Label('用户名:', style=Pack(padding=(0, 5)))

self.username_input = toga.TextInput(style=Pack(flex=1))

password_label = toga.Label('密码:', style=Pack(padding=(0, 5)))

self.password_input = toga.PasswordInput(style=Pack(flex=1))

login_button = toga.Button('登录', on_press=self.login, style=Pack(padding=5))

login_box = toga.Box(

children=[

username_label, self.username_input,

password_label, self.password_input,

login_button

],

style=Pack(direction=COLUMN, padding=10)

)

return login_box

def login(self, widget):

username = self.username_input.value

password = self.password_input.value

cursor = self.db_conn.cursor()

cursor.execute('SELECT * FROM users WHERE username=? AND password=?', (username, password))

user = cursor.fetchone()

if user is not None:

self.username_input.value = ''

self.password_input.value = ''

self.login_window.close()

self.show_main_window(user[0]) # 传递用户ID

else:

toga.dialog.info('登录失败', '用户名或密码错误。')

def show_main_window(self, user_id):

self.user_id = user_id

self.main_window = toga.MainWindow(title=self.name)

self.main_window.content = self.build_main_box()

self.main_window.show()

def add_activity(self, widget):

activity_type = self.activity_type.value

time = self.time.value

distance = float(self.distance.value)

calories = float(self.calories.value)

cursor = self.db_conn.cursor()

cursor.execute('''

INSERT INTO activities (user_id, activity_type, time, distance, calories)

VALUES (?, ?, ?, ?, ?)

''', (self.user_id, activity_type, time, distance, calories))

self.db_conn.commit()

self.activity_type.value = ''

self.time.value = ''

self.distance.value = ''

self.calories.value = ''

def calculate_weekly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE user_id=? AND time >= ? AND time <= ?

''', (self.user_id, self.get_start_of_week(), self.get_end_of_week()))

result = cursor.fetchone()

return result[0], result[1]

def calculate_monthly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE user_id=? AND time >= ? AND time <= ?

''', (self.user_id, self.get_start_of_month(), self.get_end_of_month()))

result = cursor.fetchone()

return result[0], result[1]

def calculate_yearly_stats(self):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT SUM(time), SUM(calories)

FROM activities

WHERE user_id=? AND time >= ? AND time <= ?

''', (self.user_id, self.get_start_of_year(), self.get_end_of_year()))

result = cursor.fetchone()

return result[0], result[1]

def get_start_of_week(self):

today = datetime.date.today()

start_of_week = today - datetime.timedelta(days=today.weekday())

return start_of_week.isoformat()

def get_end_of_week(self):

today = datetime.date.today()

end_of_week = today + datetime.timedelta(days=6 - today.weekday())

return end_of_week.isoformat()

def get_start_of_month(self):

today = datetime.date.today()

start_of_month = today.replace(day=1)

return start_of_month.isoformat()

def get_end_of_month(self):

today = datetime.date.today()

_, last_day = calendar.monthrange(today.year, today.month)

end_of_month = today.replace(day=last_day)

return end_of_month.isoformat()

def get_start_of_year(self):

today = datetime.date.today()

start_of_year = today.replace(month=1, day=1)

return start_of_year.isoformat()

def get_end_of_year(self):

today = datetime.date.today()

end_of_year = today.replace(month=12, day=31)

return end_of_year.isoformat()

def analyze_data(self, widget):

cursor = self.db_conn.cursor()

cursor.execute('''

SELECT activity_type, SUM(time) as total_time, SUM(calories) as total_calories

FROM activities

WHERE user_id=?

GROUP BY activity_type

''', (self.user_id,))

result = cursor.fetchall()

data = pd.DataFrame(result, columns=['Activity Type', 'Total Time', 'Total Calories'])



# 绘制柱状图

data.plot(x='Activity Type', y='Total Time', kind='bar', legend=False)

plt.title('Total Time Spent on Each Activity')

plt.xlabel('Activity Type')

plt.ylabel('Total Time (hours)')

plt.show()

# 绘制饼图

data.plot(x='Activity Type', y='Total Calories', kind='pie', labels=data['Activity Type'], autopct='%1.1f%%')

plt.title('Total Calories Burned for Each Activity')

plt.ylabel('')

plt.show()

def create_plan(self, widget):

plan_name = self.plan_name.value

plan_description = self.plan_description.value

cursor = self.db_conn.cursor()

cursor.execute('''

INSERT INTO plans (user_id, name, description)

VALUES (?, ?, ?)

''', (self.user_id, plan_name, plan_description))

self.db_conn.commit()

self.plan_name.value = ''

self.plan_description.value = ''

def view_plans(self, widget):

cursor = self.db_conn.cursor()

cursor.execute('SELECT name, description FROM plans WHERE user_id=?', (self.user_id,))

plans = cursor.fetchall()

plan_list = toga.Table(

headings=['计划名称', '计划描述'],

data=plans,

style=Pack(flex=1)

)

self.plan_window = toga.Window(title='健身计划列表')

self.plan_window.content = plan_list

self.plan_window.show()

def backup_data(self, widget):

self.db_conn.close()

shutil.copy2('fitness_tracker.db', 'backup/fitness_tracker_backup.db')

self.db_conn = sqlite3.connect('fitness_tracker.db')

toga.dialog.info('备份成功', '数据已成功备份至 backup 文件夹。')

def restore_data(self, widget):

self.db_conn.close()

shutil.copy2('backup/fitness_tracker_backup.db', 'fitness_tracker.db')

self.db_conn = sqlite3.connect('fitness_tracker.db')

toga.dialog.info('恢复成功', '数据已成功恢复。')

def build_main_box(self):

activity_label = toga.Label('运动类型:', style=Pack(padding=(0, 5)))

self.activity_type = toga.TextInput(style=Pack(flex=1))

time_label = toga.Label('时间:', style=Pack(padding=(0, 5)))

self.time = toga.TextInput(style=Pack(flex=1))

distance_label = toga.Label('距离:', style=Pack(padding=(0, 5)))

self.distance = toga.TextInput(style=Pack(flex=1))

calories_label = toga.Label('消耗卡路里:', style=Pack(padding=(0, 5)))

self.calories = toga.TextInput(style=Pack(flex=1))

add_button = toga.Button('添加运动', on_press=self.add_activity, style=Pack(padding=5))

analyze_button = toga.Button('数据分析', on_press=self.analyze_data, style=Pack(padding=5))

plan_name_label = toga.Label('计划名称:', style=Pack(padding=(0, 5)))

self.plan_name = toga.TextInput(style=Pack(flex=1))

plan_description_label = toga.Label('计划描述:', style=Pack(padding=(0, 5)))

self.plan_description = toga.TextInput(style=Pack(flex=1))

create_plan_button = toga.Button('创建计划', on_press=self.create_plan, style=Pack(padding=5))

view_plans_button = toga.Button('查看计划', on_press=self.view_plans, style=Pack(padding=5))

backup_button = toga.Button('备份数据', on_press=self.backup_data, style=Pack(padding=5))

restore_button = toga.Button('恢复数据', on_press=self.restore_data, style=Pack(padding=5))

main_box = toga.Box(

children=[

activity_label, self.activity_type, time_label, self.time,

distance_label, self.distance, calories_label, self.calories,

add_button, analyze_button,

plan_name_label, self.plan_name, plan_description_label, self.plan_description,

create_plan_button, view_plans_button,

backup_button, restore_button

],

style=Pack(direction=COLUMN, padding=10)

)

return main_box

def main():

return FitnessApp('健身追踪应用', 'com.example.fitnessapp')

if __name__ == '__main__':

main().main_loop()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469

在这里插入图片描述
上述代码是一个完整的健身追踪应用示例,包括登录验证、记录运动数据、统计分析、健身计划管理以及数据备份和恢复功能。你可以根据需要进行修改和扩展,以满足实际需求。请注意,在实际应用中,你可能需要进一步优化代码和界面设计,以提供更好的用户体验和功能。同时,建议在生产环境中使用专业的身份验证解决方案,确保应用的安全性。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/197608
推荐阅读
相关标签
  

闽ICP备14008679号