Untitled
unknown
plain_text
2 years ago
34 kB
11
Indexable
import sqlite3
import sys
from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import (QApplication, QWidget, QTableWidget, QTableWidgetItem,
QHBoxLayout, QVBoxLayout, QMenu, QAction, QDialog,
QComboBox, QLineEdit, QPushButton, QLabel, QFormLayout, QButtonGroup, QRadioButton,
QTabWidget)
def create_connection():
try:
return sqlite3.connect('nutrition.db')
except sqlite3.Error as e:
print(e)
return None
def create_table(conn):
try:
cursor = conn.cursor()
cursor.execute("""CREATE TABLE IF NOT EXISTS foods (
name TEXT NOT NULL,
calories REAL,
lipids REAL,
carbohydrates REAL,
protein REAL,
price REAL
);""")
conn.commit()
except sqlite3.Error as e:
print(e)
def insert_food(conn, food):
try:
cursor = conn.cursor()
cursor.execute("INSERT INTO foods(name, calories, lipids, carbohydrates, protein, price) VALUES (?, ?, ?, ?, ?, ?)", food)
conn.commit()
except sqlite3.Error as e:
print(e)
def get_foods(conn):
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM foods ORDER BY name ASC")
return cursor.fetchall()
except sqlite3.Error as e:
print(e)
return []
def delete_food(conn, food_name):
try:
cursor = conn.cursor()
cursor.execute("DELETE FROM foods WHERE name = ?", (food_name,))
conn.commit()
except sqlite3.Error as e:
print(e)
def update_food(conn, old_name, new_food):
try:
cursor = conn.cursor()
cursor.execute("""UPDATE foods
SET name = ?, calories = ?, lipids = ?, carbohydrates = ?, protein = ?, price = ?
WHERE name = ?""",
(*new_food, old_name))
conn.commit()
except sqlite3.Error as e:
print(e)
def create_progress_table(conn):
try:
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS progress (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
weight REAL,
body_fat REAL,
muscle_mass REAL,
waist_size REAL, -- Add waist_size column
chest_size REAL,
thigh_size REAL,
biceps_size REAL,
notes TEXT
);
""")
conn.commit()
except sqlite3.Error as e:
print(e)
def insert_progress(conn, progress):
try:
cursor = conn.cursor()
cursor.execute("INSERT INTO progress(date, weight, body_fat, muscle_mass, waist_size, chest_size, thigh_size, biceps_size, notes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", progress)
conn.commit()
except sqlite3.Error as e:
print(e)
def get_progress(conn):
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM progress ORDER BY date ASC")
return cursor.fetchall()
except sqlite3.Error as e:
print(e)
return []
def delete_progress(conn, progress_id):
try:
cursor = conn.cursor()
cursor.execute("DELETE FROM progress WHERE id = ?", (progress_id,))
conn.commit()
except sqlite3.Error as e:
print(e)
def update_progress(conn, progress_id, progress):
try:
cursor = conn.cursor()
cursor.execute("""
UPDATE progress
SET date = ?, weight = ?, body_fat = ?, muscle_mass = ?, waist_size = ?, chest_size = ?, Thigh_size = ?, Biceps_size = ?, notes = ?
WHERE id = ?
""", (*progress, progress_id))
conn.commit()
except sqlite3.Error as e:
print(e)
class AddFoodDialog(QDialog):
def __init__(self, parent=None, food=None):
super(AddFoodDialog, self).__init__(parent)
self.setWindowTitle('Add Food Item' if food is None else 'Edit Food Item')
self.layout = QFormLayout(self)
self.food = food
self.nameEdit = QLineEdit(self)
self.caloriesEdit = QLineEdit(self)
self.lipidsEdit = QLineEdit(self)
self.carbsEdit = QLineEdit(self)
self.proteinEdit = QLineEdit(self)
self.priceEdit = QLineEdit(self)
self.nameEdit.setStyleSheet("background-color: lightyellow; font-weight: bold;")
if food:
self.nameEdit.setText(food[0])
self.caloriesEdit.setText(str(food[1]))
self.lipidsEdit.setText(str(food[2]))
self.carbsEdit.setText(str(food[3]))
self.proteinEdit.setText(str(food[4]))
self.priceEdit.setText(str(food[5]))
self.layout.addRow('Name:', self.nameEdit)
self.layout.addRow('Calories:', self.caloriesEdit)
self.layout.addRow('Lipids:', self.lipidsEdit)
self.layout.addRow('Carbohydrates:', self.carbsEdit)
self.layout.addRow('Protein:', self.proteinEdit)
self.layout.addRow('Price:', self.priceEdit)
self.addButton = QPushButton('Add' if food is None else 'Update', self)
self.cancelButton = QPushButton('Cancel', self)
self.addButton.clicked.connect(self.add_food)
self.cancelButton.clicked.connect(self.reject)
buttonLayout = QHBoxLayout()
buttonLayout.addWidget(self.addButton)
buttonLayout.addWidget(self.cancelButton)
self.layout.addRow(buttonLayout)
def add_food(self):
try:
name = self.nameEdit.text()
calories = float(self.caloriesEdit.text())
lipids = float(self.lipidsEdit.text())
carbs = float(self.carbsEdit.text())
protein = float(self.proteinEdit.text())
price = float(self.priceEdit.text())
food = (name, calories, lipids, carbs, protein, price)
if self.food:
old_name = self.food[0]
update_food(conn, old_name, food)
else:
insert_food(conn, food)
self.accept() # Close the dialog on success
except ValueError:
# Handle invalid input
pass
class FoodDatabaseDialog(QDialog):
foodAdded = pyqtSignal() # Signal to emit when food is added or updated
foodDeleted = pyqtSignal() # New signal for when a food is deleted
def __init__(self, parent=None):
super(FoodDatabaseDialog, self).__init__(parent)
self.setWindowTitle('Food Database')
self.setGeometry(300, 300, 500, 400)
self.layout = QVBoxLayout(self)
addButton = QPushButton('Add Food', self)
deleteButton = QPushButton('Delete Selected Food', self)
addButton.setStyleSheet("background-color: navy; color: white;")
deleteButton.setStyleSheet("background-color: red; color: white;")
addButton.clicked.connect(self.open_add_dialog)
deleteButton.clicked.connect(self.delete_food)
buttonLayout = QHBoxLayout()
buttonLayout.addWidget(addButton)
buttonLayout.addWidget(deleteButton)
self.layout.addLayout(buttonLayout)
self.table = QTableWidget(self)
self.table.setColumnCount(6)
self.table.setHorizontalHeaderLabels(['Name', 'Calories', 'Lipids', 'Carbohydrates', 'Protein', 'Price'])
self.table.setContextMenuPolicy(Qt.CustomContextMenu)
self.table.customContextMenuRequested.connect(self.show_context_menu)
self.update_table()
self.layout.addWidget(self.table)
def show_context_menu(self, position):
menu = QMenu(self)
edit_action = QAction("Edit", self)
edit_action.triggered.connect(self.edit_food)
menu.addAction(edit_action)
menu.exec_(self.table.mapToGlobal(position))
def edit_food(self):
selected_row = self.table.currentRow()
if selected_row >= 0:
name = self.table.item(selected_row, 0).text()
calories = float(self.table.item(selected_row, 1).text())
lipids = float(self.table.item(selected_row, 2).text())
carbs = float(self.table.item(selected_row, 3).text())
protein = float(self.table.item(selected_row, 4).text())
price = float(self.table.item(selected_row, 5).text())
food = (name, calories, lipids, carbs, protein, price)
dialog = AddFoodDialog(self, food)
if dialog.exec_():
self.update_table()
self.foodAdded.emit() # Emit the signal after the dialog has successfully added or edited a food
def open_add_dialog(self):
dialog = AddFoodDialog(self)
if dialog.exec_():
self.update_table()
self.foodAdded.emit() # Emit the signal after the dialog has successfully added a food
def delete_food(self):
selected_row = self.table.currentRow()
if selected_row >= 0:
food_name = self.table.item(selected_row, 0).text()
delete_food(conn, food_name)
self.update_table()
self.foodDeleted.emit() # Emit the signal after the food is deleted
def update_table(self):
foods = get_foods(conn)
self.table.setRowCount(len(foods))
for i, (name, calories, lipids, carbs, protein, price) in enumerate(foods):
nameItem = QTableWidgetItem(name)
nameItem.setBackground(QColor(173, 216, 230))
self.table.setItem(i, 0, nameItem)
self.table.setItem(i, 1, QTableWidgetItem(str(calories)))
self.table.setItem(i, 2, QTableWidgetItem(str(lipids)))
self.table.setItem(i, 3, QTableWidgetItem(str(carbs)))
self.table.setItem(i, 4, QTableWidgetItem(str(protein)))
self.table.setItem(i, 5, QTableWidgetItem(str(price)))
class MealPlannerDialog(QDialog):
def __init__(self, parent=None):
super(MealPlannerDialog, self).__init__(parent)
self.setWindowTitle('Meal Planner')
self.setGeometry(300, 300, 600, 500)
self.layout = QVBoxLayout(self)
self.conn = create_connection()
self.genderCombo = QComboBox(self)
self.genderCombo.addItems(['Male', 'Female'])
self.weightEdit = QLineEdit(self)
self.heightEdit = QLineEdit(self)
self.ageEdit = QLineEdit(self)
self.bodyFatEdit = QLineEdit(self)
self.activityCombo = QComboBox(self)
self.activityCombo.addItems([
'Sedentary (little or no exercise)',
'Lightly active (exercise 1-3 times/week)',
'Active (daily exercise or intense exercise 3-4 times/week)',
'Very active (intense exercise 6-7 times/week)',
'Super active (very intense exercise daily, or physical job)'
])
self.primaryGoalCombo = QComboBox(self)
self.primaryGoalCombo.addItems([
'Build Muscle (Male - Body Fat % ≤ 8-12, Female - Body Fat % ≤ 18-22)',
'Lose Fat & Build Muscle Equally (Male - Body Fat % ≈ 12-18, Female - Body Fat % ≈ 22-28)',
'Lose Fat (Male - Body Fat % ≥ 18-20+, Female - Body Fat % ≥ 28-30+)'
])
self.trainingExperienceGroup = QButtonGroup(self)
self.beginnerRadio = QRadioButton("Beginner (0-2 years of lifting)")
self.intermediateRadio = QRadioButton("Intermediate (2-5 years of lifting)")
self.advancedRadio = QRadioButton("Advanced (5+ years of lifting)")
self.trainingExperienceGroup.addButton(self.beginnerRadio)
self.trainingExperienceGroup.addButton(self.intermediateRadio)
self.trainingExperienceGroup.addButton(self.advancedRadio)
calculatorLayout = QFormLayout()
calculatorLayout.addRow('Gender:', self.genderCombo)
calculatorLayout.addRow('Weight (kg):', self.weightEdit)
calculatorLayout.addRow('Height (cm):', self.heightEdit)
calculatorLayout.addRow('Age (years):', self.ageEdit)
calculatorLayout.addRow('Body Fat %:', self.bodyFatEdit)
calculatorLayout.addRow('Activity Level:', self.activityCombo)
calculatorLayout.addRow('Primary Goal:', self.primaryGoalCombo)
calculatorLayout.addRow("Training Experience:", self.beginnerRadio)
calculatorLayout.addRow("", self.intermediateRadio)
calculatorLayout.addRow("", self.advancedRadio)
self.layout.addLayout(calculatorLayout)
self.totalPriceLabel = QLabel('Total Price: €0.00', self) # Add this line
self.layout.addWidget(self.totalPriceLabel) # Add this line
self.needsDisplay = QLabel('Daily Needs: ', self)
calculatorLayout.addRow(self.needsDisplay)
self.mealTypeCombo = QComboBox(self)
self.mealTypeCombo.addItems(['Breakfast', 'Lunch', 'Snack', 'Dinner'])
self.foodCombo = QComboBox(self)
self.foodCombo.setMinimumWidth(200) # Set the minimum width to 200 pixels or another value that fits your needs
self.quantityEdit = QLineEdit(self)
self.addButton = QPushButton('Add Meal', self)
self.clearAllButton = QPushButton('Clear All', self)
self.deleteMealButton = QPushButton('Delete Meal', self)
self.clearAllButton.clicked.connect(self.clear_meals)
self.clearAllButton.setFixedSize(100, 30)
self.addButton.clicked.connect(self.add_food_to_meal)
self.deleteMealButton.clicked.connect(self.delete_selected_meal)
self.mealTable = QTableWidget(self)
self.mealTable.setColumnCount(8) # Adjusted for detailed nutritional info
self.mealTable.setHorizontalHeaderLabels(
['Meal', 'Food', 'Quantity (g)', 'Calories (kcal)', 'Proteins (g)', 'Carbs (g)', 'Fats (g)', 'Price (€)'])
# Layout for Meal Creation
mealCreationLayout = QHBoxLayout()
mealCreationLayout.addWidget(self.mealTypeCombo)
mealCreationLayout.addWidget(self.foodCombo, 1) # Stretch factor for better spacing
mealCreationLayout.addWidget(self.quantityEdit)
mealCreationLayout.addWidget(self.addButton)
mealCreationLayout.addWidget(self.deleteMealButton) # Add the delete button to the layout
mealCreationLayout.addWidget(self.clearAllButton)
self.layout.addLayout(mealCreationLayout)
self.layout.addWidget(self.mealTable)
# Ensure this is called to fetch database information
self.populate_food_combo()
self.total_calories = 0.0
self.total_proteins = 0.0
self.total_carbs = 0.0
self.total_fats = 0.0
self.daily_caloric_needs = 0.0
self.layout.addLayout(mealCreationLayout)
self.layout.addWidget(self.mealTable)
# Connect signals to slots
self.connect_signals()
def connect_signals(self):
# Connect signals from input widgets to the calculate_needs method
self.genderCombo.currentIndexChanged.connect(self.calculate_needs)
self.weightEdit.textChanged.connect(self.calculate_needs)
self.heightEdit.textChanged.connect(self.calculate_needs)
self.ageEdit.textChanged.connect(self.calculate_needs)
self.bodyFatEdit.textChanged.connect(self.calculate_needs)
self.activityCombo.currentIndexChanged.connect(self.calculate_needs)
self.primaryGoalCombo.currentIndexChanged.connect(self.calculate_needs)
self.trainingExperienceGroup.buttonClicked.connect(self.calculate_needs)
def populate_food_combo(self):
foods = get_foods(self.conn)
self.foodCombo.clear() # Clear existing items before adding new ones
for food in foods:
self.foodCombo.addItem(food[0])
def add_food_to_meal(self):
try:
meal_type = self.mealTypeCombo.currentText()
food_name = self.foodCombo.currentText()
# Check if quantity input is empty
if self.quantityEdit.text().strip() == '':
raise ValueError("Quantity cannot be empty")
quantity = float(self.quantityEdit.text())
food_nutrition = self.get_nutritional_values(food_name, quantity)
# Calculate total price
total_price = food_nutrition['price'] * quantity
# Update total nutritional values and total price
self.total_calories += food_nutrition['calories']
self.total_proteins += food_nutrition['proteins']
self.total_carbs += food_nutrition['carbs']
self.total_fats += food_nutrition['fats']
self.update_intake_ratio_display()
# Add meal data to the table
row_position = self.mealTable.rowCount()
self.mealTable.insertRow(row_position)
self.mealTable.setItem(row_position, 0, QTableWidgetItem(meal_type))
self.mealTable.setItem(row_position, 1, QTableWidgetItem(food_name))
self.mealTable.setItem(row_position, 2, QTableWidgetItem(str(quantity)))
self.mealTable.setItem(row_position, 3, QTableWidgetItem(str(food_nutrition['calories'])))
self.mealTable.setItem(row_position, 4, QTableWidgetItem(str(food_nutrition['proteins'])))
self.mealTable.setItem(row_position, 5, QTableWidgetItem(str(food_nutrition['carbs'])))
self.mealTable.setItem(row_position, 6, QTableWidgetItem(str(food_nutrition['fats'])))
self.mealTable.setItem(row_position, 7, QTableWidgetItem(str(total_price))) # Display total price
# Recalculate nutritional needs
self.calculate_needs()
# Update total price label
self.update_total_price()
except ValueError as ve:
print(f"Error adding food to meal: {ve}")
def update_total_price(self):
total_price = sum(float(self.mealTable.item(row, 7).text()) for row in range(self.mealTable.rowCount()))
self.totalPriceLabel.setText(f'Total Price: €{total_price:.2f}') # Update the label here
def get_nutritional_values(self, food_name, quantity):
food_data = next((food for food in get_foods(self.conn) if food[0] == food_name), None)
if food_data:
return {
'calories': food_data[1] * quantity,
'proteins': food_data[4] * quantity,
'carbs': food_data[3] * quantity,
'fats': food_data[2] * quantity,
'price': food_data[5] # Fetch price from database
}
else:
return {'calories': 0, 'proteins': 0, 'carbs': 0, 'fats': 0, 'price': 0}
def update_intake_ratio_display(self):
if self.daily_caloric_needs > 0:
# Assuming self.daily_protein_needs, self.daily_carbs_needs, and self.daily_fats_needs are also calculated and stored
caloric_ratio = self.total_calories / self.daily_caloric_needs
protein_ratio = self.total_proteins / self.daily_protein_needs if self.daily_protein_needs > 0 else 0
carbs_ratio = self.total_carbs / self.daily_carbs_needs if self.daily_carbs_needs > 0 else 0
fats_ratio = self.total_fats / self.daily_fats_needs if self.daily_fats_needs > 0 else 0
self.needsDisplay.setText(f"Daily Nutritional Needs:\n"
f"Calories: {self.total_calories:.2f} kcal / {self.daily_caloric_needs:.2f} kcal\n"
f"Protein: {self.total_proteins:.2f} g / {self.daily_protein_needs:.2f} g\n"
f"Carbs: {self.total_carbs:.2f} g / {self.daily_carbs_needs:.2f} g\n"
f"Fats: {self.total_fats:.2f} g / {self.daily_fats_needs:.2f} g")
else:
self.needsDisplay.setText("Daily Nutritional Needs: N/A")
def calculate_needs(self):
try:
gender = self.genderCombo.currentText()
weight = float(self.weightEdit.text()) # Weight in kilograms
height = float(self.heightEdit.text()) # Height in centimeters
age = int(self.ageEdit.text())
activity_level = self.activityCombo.currentText()
primary_goal = self.primaryGoalCombo.currentText()
training_experience = self.get_selected_training_experience()
# Calculate BMR using Mifflin-St Jeor formula
bmr = 10 * weight + 6.25 * height - 5 * age + (5 if gender == 'Male' else -161)
# Adjust for activity level
activity_factors = {
'Sedentary (little or no exercise)': 1.2,
'Lightly active (exercise 1-3 times/week)': 1.375,
'Active (daily exercise or intense exercise 3-4 times/week)': 1.55,
'Very active (intense exercise 6-7 times/week)': 1.725,
'Super active (very intense exercise daily, or physical job)': 1.9
}
maintenance_calories = bmr * activity_factors[activity_level]
# Adjust caloric needs based on primary goal and training experience
if 'Lose Fat & Build Muscle Equally' in primary_goal:
self.daily_caloric_needs = maintenance_calories
elif 'Build Muscle' in primary_goal:
if training_experience == 'Beginner (0-2 years of lifting)':
self.daily_caloric_needs = maintenance_calories * 1.25
elif training_experience == 'Intermediate (2-5 years of lifting)':
self.daily_caloric_needs = maintenance_calories * 1.175
else: # Advanced (5+ years of lifting)
self.daily_caloric_needs = maintenance_calories * 1.15
else: # 'Lose Fat'
self.daily_caloric_needs = maintenance_calories * 0.85 # Adjust as needed
# Example calculations for protein, carbs, and fat needs
self.daily_protein_needs = weight * 1.6 # Example: 1.6g per kg of body weight
self.daily_carbs_needs = (self.daily_caloric_needs * 0.5) / 4 # Example: 50% of calories from carbs
self.daily_fats_needs = (self.daily_caloric_needs * 0.25) / 9 # Example: 25% of calories from fats
self.needsDisplay.setText(f"Daily Nutritional Needs:\n"
f"Calories: {self.daily_caloric_needs:.2f} kcal\n"
f"Protein: {self.daily_protein_needs:.2f} g\n"
f"Carbs: {self.daily_carbs_needs:.2f} g\n"
f"Fats: {self.daily_fats_needs:.2f} g")
self.update_intake_ratio_display()
except ValueError:
self.needsDisplay.setText("Invalid input. Please enter correct values.")
def get_selected_training_experience(self):
selected_button = self.trainingExperienceGroup.checkedButton()
if selected_button:
return selected_button.text()
return "Unknown"
def delete_selected_meal(self):
selected_row = self.mealTable.currentRow()
if selected_row != -1: # -1 means no row is selected
# Update total price by subtracting the price of the deleted meal
deleted_price = float(self.mealTable.item(selected_row, 7).text())
self.total_calories -= float(self.mealTable.item(selected_row, 3).text())
self.total_proteins -= float(self.mealTable.item(selected_row, 4).text())
self.total_carbs -= float(self.mealTable.item(selected_row, 5).text())
self.total_fats -= float(self.mealTable.item(selected_row, 6).text())
self.mealTable.removeRow(selected_row)
self.update_total_price() # Update the total price after deletion
# Recalculate nutritional needs
self.calculate_needs()
def clear_meals(self):
# Clear the meal table
self.mealTable.setRowCount(0)
# Reset total nutritional values
self.total_calories = 0.0
self.total_proteins = 0.0
self.total_carbs = 0.0
self.total_fats = 0.0
# Update the display
self.update_intake_ratio_display()
# Update the total price label
self.update_total_price()
def update_food_combo(self):
self.foodCombo.clear() # Clear the existing items
self.populate_food_combo() # Repopulate the combo box
def update_total_nutrition(self):
# Reset total nutritional values
self.total_calories = 0.0
self.total_proteins = 0.0
self.total_carbs = 0.0
self.total_fats = 0.0
# Recalculate totals based on remaining items in the table
for row in range(self.mealTable.rowCount()):
# Assuming calories, proteins, carbs, and fats are in columns 3, 4, 5, and 6
self.total_calories += float(self.mealTable.item(row, 3).text())
self.total_proteins += float(self.mealTable.item(row, 4).text())
self.total_carbs += float(self.mealTable.item(row, 5).text())
self.total_fats += float(self.mealTable.item(row, 6).text())
# Update display of totals
self.update_intake_ratio_display()
class AddProgressDialog(QDialog):
def __init__(self, parent=None, progress=None):
super(AddProgressDialog, self).__init__(parent)
self.setWindowTitle('Add Measurement Entry' if progress is None else 'Edit Measurement Entry')
self.layout = QFormLayout(self)
self.progress = progress
self.dateEdit = QLineEdit(self)
self.weightEdit = QLineEdit(self)
self.bodyFatEdit = QLineEdit(self)
self.muscleMassEdit = QLineEdit(self)
self.waistSizeEdit = QLineEdit(self)
self.chestSizeEdit = QLineEdit(self)
self.thighSizeEdit = QLineEdit(self)
self.bicepsSizeEdit = QLineEdit(self)
self.notesEdit = QLineEdit(self) # Define notesEdit
if progress:
self.dateEdit.setText(progress[1])
self.weightEdit.setText(str(progress[2]))
self.bodyFatEdit.setText(str(progress[3]))
self.muscleMassEdit.setText(str(progress[4]))
self.waistSizeEdit.setText(str(progress[5]))
self.chestSizeEdit.setText(str(progress[6]))
self.thighSizeEdit.setText(str(progress[7]))
self.bicepsSizeEdit.setText(str(progress[8]))
self.notesEdit.setText(progress[9]) # Set text for notesEdit
self.layout.addRow('Date:', self.dateEdit)
self.layout.addRow('Weight (kg):', self.weightEdit)
self.layout.addRow('Body Fat (%):', self.bodyFatEdit)
self.layout.addRow('Muscle Mass (%):', self.muscleMassEdit)
self.layout.addRow('Waist Size (cm) :', self.waistSizeEdit)
self.layout.addRow('Chest Size (cm) :', self.chestSizeEdit)
self.layout.addRow('Thigh Size (cm) :', self.thighSizeEdit)
self.layout.addRow('Biceps Size (cm) :', self.bicepsSizeEdit)
self.layout.addRow('Notes:', self.notesEdit) # Add notesEdit to layout
self.addButton = QPushButton('Add' if progress is None else 'Update', self)
self.cancelButton = QPushButton('Cancel', self)
self.addButton.clicked.connect(self.add_progress)
self.cancelButton.clicked.connect(self.reject)
buttonLayout = QHBoxLayout()
buttonLayout.addWidget(self.addButton)
buttonLayout.addWidget(self.cancelButton)
self.layout.addRow(buttonLayout)
def add_progress(self):
try:
date = self.dateEdit.text()
weight = float(self.weightEdit.text())
body_fat = float(self.bodyFatEdit.text())
muscle_mass = float(self.muscleMassEdit.text())
waist_size = float(self.waistSizeEdit.text())
chest_size = float(self.chestSizeEdit.text())
thigh_size = float(self.thighSizeEdit.text())
biceps_size = float(self.bicepsSizeEdit.text())
notes = self.notesEdit.text()
progress = (date, weight, body_fat, muscle_mass, waist_size, chest_size, thigh_size, biceps_size, notes)
if self.progress:
update_progress(conn, self.progress[0], progress)
else:
insert_progress(conn, progress)
self.accept()
except ValueError:
pass
class ProgressDialog(QDialog):
def __init__(self, parent=None):
super(ProgressDialog, self).__init__(parent)
self.setWindowTitle('Body Measurements Tracker')
self.setGeometry(300, 300, 600, 400)
self.layout = QVBoxLayout(self)
addButton = QPushButton('Add Measurement Entry', self)
deleteButton = QPushButton('Delete Selected Entry', self)
addButton.clicked.connect(self.open_add_dialog)
deleteButton.clicked.connect(self.delete_progress)
buttonLayout = QHBoxLayout()
buttonLayout.addWidget(addButton)
buttonLayout.addWidget(deleteButton)
self.layout.addLayout(buttonLayout)
self.table = QTableWidget(self)
self.table.setColumnCount(10) # Adjust column count to match the number of columns
self.table.setHorizontalHeaderLabels(['ID', 'Date', 'Weight', 'Body Fat', 'Muscle Mass', 'Waist Size', 'Chest Size', 'Thigh Size', 'Biceps Size', 'Notes'])
self.table.setContextMenuPolicy(Qt.CustomContextMenu)
self.table.customContextMenuRequested.connect(self.show_context_menu)
self.update_table()
self.layout.addWidget(self.table)
def show_context_menu(self, position):
menu = QMenu(self)
edit_action = QAction("Edit", self)
edit_action.triggered.connect(self.edit_progress)
menu.addAction(edit_action)
menu.exec_(self.table.mapToGlobal(position))
def edit_progress(self):
selected_row = self.table.currentRow()
if selected_row >= 0:
progress_id = int(self.table.item(selected_row, 0).text())
date = self.table.item(selected_row, 1).text()
weight = float(self.table.item(selected_row, 2).text())
body_fat = float(self.table.item(selected_row, 3).text())
muscle_mass = float(self.table.item(selected_row, 4).text())
waist_size = float(self.table.item(selected_row, 5).text())
chest_size = float(self.table.item(selected_row, 6).text())
thigh_size = float(self.table.item(selected_row, 7).text())
biceps_size = float(self.table.item(selected_row, 8).text())
notes = self.table.item(selected_row, 9).text()
progress = (progress_id, date, weight, body_fat, muscle_mass, waist_size, chest_size, thigh_size, biceps_size, notes)
dialog = AddProgressDialog(self, progress)
if dialog.exec_():
self.update_table()
def open_add_dialog(self):
dialog = AddProgressDialog(self)
if dialog.exec_():
self.update_table()
def delete_progress(self):
selected_row = self.table.currentRow()
if selected_row >= 0:
progress_id = int(self.table.item(selected_row, 0).text())
delete_progress(conn, progress_id)
self.update_table()
def update_table(self):
progress_data = get_progress(conn)
self.table.setRowCount(len(progress_data))
for i, (progress_id, date, weight, body_fat, muscle_mass, waist_size, chest_size, thigh_size, biceps_size, notes) in enumerate(progress_data):
self.table.setItem(i, 0, QTableWidgetItem(str(progress_id)))
self.table.setItem(i, 1, QTableWidgetItem(date))
self.table.setItem(i, 2, QTableWidgetItem(str(weight)))
self.table.setItem(i, 3, QTableWidgetItem(str(body_fat)))
self.table.setItem(i, 4, QTableWidgetItem(str(muscle_mass)))
self.table.setItem(i, 5, QTableWidgetItem(str(waist_size)))
self.table.setItem(i, 6, QTableWidgetItem(str(chest_size)))
self.table.setItem(i, 7, QTableWidgetItem(str(thigh_size)))
self.table.setItem(i, 8, QTableWidgetItem(str(biceps_size)))
self.table.setItem(i, 9, QTableWidgetItem(notes))
self.table.hideColumn(0)
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 800, 600)
self.setWindowTitle('NutriGeniePro')
# Create the tab widget
tabWidget = QTabWidget(self)
foodDatabaseTab = FoodDatabaseDialog()
mealPlannerTab = MealPlannerDialog()
progressTab = ProgressDialog()
# Connect signals to slots if necessary
foodDatabaseTab.foodAdded.connect(mealPlannerTab.update_food_combo)
foodDatabaseTab.foodDeleted.connect(mealPlannerTab.update_food_combo)
# Add tabs to the tab widget
tabWidget.addTab(foodDatabaseTab, "Food Database")
tabWidget.addTab(mealPlannerTab, "Meal Planner")
tabWidget.addTab(progressTab, "Body Measurements Tracker")
# Set the layout
layout = QVBoxLayout(self)
layout.addWidget(tabWidget)
self.setLayout(layout)
if __name__ == '__main__':
conn = create_connection()
create_table(conn)
create_progress_table(conn)
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())Editor is loading...
Leave a Comment