class ExercisesAndWorkouts(QWidget): show_muscle_group_signal = pyqtSignal(str) def __init__(self): super().__init__() self.setStyleSheet(""" QWidget{ color:#c7c7c7; font-weight: bold; } QPushButton{ background-color: rgba(0, 0, 0, 0); border: 1px solid; font-size: 18px; font-weight: bold; border-color: #808080; min-height: 28px; white-space:nowrap; text-align: left; padding-left: 5%; font-family: Montserrat; } QPushButton:hover:!pressed{ border: 2px solid; border-color: #747474; } QPushButton:pressed{ border: 2px solid; background-color: #323232; border-color: #6C6C6C; }""") self.db_wrapper = DatabaseWrapper() self.table_name = "Workouts" self.db_wrapper.create_local_table(self.table_name) if self.db_wrapper.local_table_is_empty(self.table_name): self.db_wrapper.insert_default_values(self.table_name) self.fetched_my_workouts = json.loads(self.db_wrapper.fetch_local_column(self.table_name, "my_workouts")) self.create_panel() def create_panel(self): self.grid = QGridLayout() self.grid.addWidget(self.create_my_workouts(), 0, 0) self.grid.addWidget(self.create_muscle_groups(), 0, 1) self.setLayout(self.grid) def create_my_workouts(self): frame = QFrame() frame.setFrameStyle(QFrame.StyledPanel) layout = QVBoxLayout() self.workouts_layout = QVBoxLayout() self.workouts_layout.setAlignment(Qt.AlignTop) label_layout = QHBoxLayout() label_layout.setAlignment(Qt.AlignCenter) label = QLabel("My Workouts") label.setFont(QFont("Ariel", 18, weight=QFont.Bold)) label_layout.addWidget(label) self.workouts_layout.addLayout(label_layout) if len(self.fetched_my_workouts.keys()) > 0: self.buttons = [None] * len(self.fetched_my_workouts.keys()) for i, workout in enumerate(self.fetched_my_workouts.keys()): self.buttons[i] = QPushButton(workout) self.buttons[i].setProperty("button_index", i) self.buttons[i].clicked.connect(partial(self.select_button, self.buttons[i].property("button_index"))) self.workouts_layout.addWidget(self.buttons[i]) buttons_layout = QHBoxLayout() create_new_workout_button = QPushButton("Create New Workout") create_new_workout_button.clicked.connect(lambda: self.create_new_workout()) edit_workout_button = QPushButton("Edit Workout") edit_workout_button.clicked.connect(lambda: self.edit_workout()) buttons_layout.addWidget(create_new_workout_button) buttons_layout.addWidget(edit_workout_button) layout.addLayout(self.workouts_layout) layout.addLayout(buttons_layout) frame.setLayout(layout) return frame def create_muscle_groups(self): frame = QFrame() frame.setFrameStyle(QFrame.StyledPanel) layout = QVBoxLayout() layout.setAlignment(Qt.AlignTop) label_layout = QHBoxLayout() label = QLabel("Exercises by muscle group", self) label.setFont(QFont("Ariel", 15)) label_layout.addWidget(label) grid_layout = QGridLayout() grid_layout.setAlignment(Qt.AlignCenter) chest_muscle_group = QVBoxLayout() chest_image = QPushButton(self) chest_image.setIcon(QIcon(muscle_groups["Chest"])) chest_image.setIconSize(QSize(100, 100)) chest_image.resize(100, 100) chest_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") chest_image.setCursor(Qt.PointingHandCursor) chest_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Chest")) chest_label = QLabel("Chest", self) chest_label.setAlignment(Qt.AlignCenter) chest_muscle_group.addWidget(chest_image) chest_muscle_group.addWidget(chest_label) back_muscle_group = QVBoxLayout() back_image = QPushButton(self) back_image.setIcon(QIcon(muscle_groups["Back"])) back_image.setIconSize(QSize(100, 100)) back_image.resize(100, 100) back_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") back_image.setCursor(Qt.PointingHandCursor) back_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Back")) back_label = QLabel("Back", self) back_label.setAlignment(Qt.AlignCenter) back_muscle_group.addWidget(back_image) back_muscle_group.addWidget(back_label) triceps_muscle_group = QVBoxLayout() triceps_image = QPushButton(self) triceps_image.setIcon(QIcon(muscle_groups["Triceps"])) triceps_image.setIconSize(QSize(100, 100)) triceps_image.resize(100, 100) triceps_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") triceps_image.setCursor(Qt.PointingHandCursor) triceps_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Triceps")) triceps_label = QLabel("Triceps", self) triceps_label.setAlignment(Qt.AlignCenter) triceps_muscle_group.addWidget(triceps_image) triceps_muscle_group.addWidget(triceps_label) biceps_muscle_group = QVBoxLayout() biceps_image = QPushButton(self) biceps_image.setIcon(QIcon(muscle_groups["Biceps"])) biceps_image.setIconSize(QSize(100, 100)) biceps_image.resize(100, 100) biceps_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") biceps_image.setCursor(Qt.PointingHandCursor) biceps_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Biceps")) biceps_label = QLabel("Biceps", self) biceps_label.setAlignment(Qt.AlignCenter) biceps_muscle_group.addWidget(biceps_image) biceps_muscle_group.addWidget(biceps_label) shoulders_muscle_group = QVBoxLayout() shoulders_image = QPushButton(self) shoulders_image.setIcon(QIcon(muscle_groups["Shoulders"])) shoulders_image.setIconSize(QSize(100, 100)) shoulders_image.resize(100, 100) shoulders_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") shoulders_image.setCursor(Qt.PointingHandCursor) shoulders_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Shoulders")) shoulders_label = QLabel("Shoulders", self) shoulders_label.setAlignment(Qt.AlignCenter) shoulders_muscle_group.addWidget(shoulders_image) shoulders_muscle_group.addWidget(shoulders_label) core_muscle_group = QVBoxLayout() core_image = QPushButton(self) core_image.setIcon(QIcon(muscle_groups["Core"])) core_image.setIconSize(QSize(100, 100)) core_image.resize(100, 100) core_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") core_image.setCursor(Qt.PointingHandCursor) core_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Core")) core_label = QLabel("Core", self) core_label.setAlignment(Qt.AlignCenter) core_muscle_group.addWidget(core_image) core_muscle_group.addWidget(core_label) quadriceps_muscle_group = QVBoxLayout() quadriceps_image = QPushButton(self) quadriceps_image.setIcon(QIcon(muscle_groups["Quadriceps"])) quadriceps_image.setIconSize(QSize(100, 100)) quadriceps_image.resize(100, 100) quadriceps_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") quadriceps_image.setCursor(Qt.PointingHandCursor) quadriceps_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Legs")) quadriceps_label = QLabel("Quadriceps", self) quadriceps_label.setAlignment(Qt.AlignCenter) quadriceps_muscle_group.addWidget(quadriceps_image) quadriceps_muscle_group.addWidget(quadriceps_label) calves_muscle_group = QVBoxLayout() calves_image = QPushButton(self) calves_image.setIcon(QIcon(muscle_groups["Calves"])) calves_image.setIconSize(QSize(100, 100)) calves_image.resize(100, 100) calves_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") calves_image.setCursor(Qt.PointingHandCursor) calves_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Calves")) calves_label = QLabel("Calves", self) calves_label.setAlignment(Qt.AlignCenter) calves_muscle_group.addWidget(calves_image) calves_muscle_group.addWidget(calves_label) hamstrings_muscle_group = QVBoxLayout() hamstrings_image = QPushButton(self) hamstrings_image.setIcon(QIcon(muscle_groups["Hamstrings"])) hamstrings_image.setIconSize(QSize(100, 100)) hamstrings_image.resize(100, 100) hamstrings_image.setStyleSheet("border: none; padding-left: 50%; background-color: white;") hamstrings_image.setCursor(Qt.PointingHandCursor) hamstrings_image.clicked.connect(lambda: self.show_muscle_group_signal.emit("Legs")) hamstrings_label = QLabel("Hamstrings", self) hamstrings_label.setAlignment(Qt.AlignCenter) hamstrings_muscle_group.addWidget(hamstrings_image) hamstrings_muscle_group.addWidget(hamstrings_label) grid_layout.addLayout(chest_muscle_group, 0, 0) grid_layout.addLayout(back_muscle_group, 0, 1) grid_layout.addLayout(triceps_muscle_group, 0, 2) grid_layout.addLayout(biceps_muscle_group, 1, 0) grid_layout.addLayout(shoulders_muscle_group, 1, 1) grid_layout.addLayout(core_muscle_group, 1, 2) grid_layout.addLayout(quadriceps_muscle_group, 2, 0) grid_layout.addLayout(calves_muscle_group, 2, 1) grid_layout.addLayout(hamstrings_muscle_group, 2, 2) layout.addLayout(label_layout) layout.addWidget(QLabel(" ")) layout.addLayout(grid_layout) frame.setLayout(layout) return frame def create_new_workout(self): self.create_workout_window = CreateWorkoutWindow() self.create_workout_window.refresh_after_creating_signal.connect(lambda signal: self.refresh_my_workouts_after_create(signal)) self.create_workout_window.setGeometry(100, 200, 300, 300) self.create_workout_window.show() def edit_workout(self): selected_button = None try: for button in self.buttons: if button.isFlat(): selected_button = button if selected_button != None: self.edit_workout_window = CreateWorkoutWindow(selected_button.text()) self.edit_workout_window.refresh_my_workouts_signal.connect(lambda workout_name: self.refresh_my_workouts(workout_name)) self.edit_workout_window.setGeometry(100, 200, 300, 300) self.edit_workout_window.show() except AttributeError: # no workouts return def select_button(self, button_index): for button in self.buttons: if button.isFlat(): button.setFlat(False) button.setStyleSheet("") button.setStyleSheet(""" QPushButton{ background-color: rgba(0, 0, 0, 0); border: 1px solid; font-size: 18px; font-weight: bold; border-color: #808080; min-height: 28px; white-space:nowrap; text-align: left; padding-left: 5%; font-family: Montserrat; } QPushButton:hover:!pressed{ border: 2px solid; border-color: #747474; } QPushButton:pressed:{ border: 2px solid; background-color: #323232; border-color: #6C6C6C; }""") self.buttons[button_index].setFlat(True) self.buttons[button_index].setStyleSheet("background-color: #323232; border-color: #6C6C6C; border: 2px solid;") @pyqtSlot(str) def refresh_my_workouts(self, workout_name): for button in self.buttons: if button.text() == workout_name: button.setParent(None) @pyqtSlot(bool) def refresh_my_workouts_after_create(self, signal): if signal: self.fetched_my_workouts = json.loads(self.db_wrapper.fetch_local_column(self.table_name, "my_workouts")) for i in reversed(range(self.workouts_layout.count())): if self.workouts_layout.itemAt(i).widget() != None: self.workouts_layout.itemAt(i).widget().setParent(None) if len(self.fetched_my_workouts.keys()) > 0: self.buttons = [None] * len(self.fetched_my_workouts.keys()) for i, workout in enumerate(self.fetched_my_workouts.keys()): self.buttons[i] = QPushButton(workout) self.buttons[i].setProperty("button_index", i) self.buttons[i].clicked.connect(partial(self.select_button, self.buttons[i].property("button_index"))) self.workouts_layout.addWidget(self.buttons[i])
class MainPanel(QWidget): emit_layout_name = pyqtSignal(str) def __init__(self): super().__init__() self.db_wrapper = DatabaseWrapper() self.setStyleSheet(""" QWidget{ background-position: center; font-family: Montserrat; color: #D9D9D9; font-size: 14px; } QPushButton{ border-radius: 1px; background-color: #440D0F; } QPushButton:hover:!pressed{ background-color: #5D1A1D } QPushButton:pressed{ background-color: #551812 } QLineEdit{ padding: 6px; background-color: rgb(33,33,33); border-radius: 2px; } """) self.create_panel() def create_panel(self): grid = QGridLayout() grid.setContentsMargins(0, 0, 0, 0) grid.addLayout(self.create_login(), 0, 0, 1, 1) self.setLayout(grid) def create_login(self): title_frame = QFrame() title_layout = QVBoxLayout() #TEMP USED AS LOGO login_label = QLabel() pixmap = QPixmap(icon_path) login_label.setPixmap(pixmap) login_label.setAlignment(Qt.AlignCenter) login_label.setAlignment(Qt.AlignCenter) login_label.setStyleSheet("font-size: 48px;") title_layout.addWidget(login_label) title_frame.setLayout(title_layout) form_layout = self.create_form_layout() wrapper_layout = QVBoxLayout() wrapper_vspacer = QSpacerItem(0, 150, QSizePolicy.Minimum, QSizePolicy.Expanding) wrapper_titleform_spacer = QSpacerItem(0, 50, QSizePolicy.Minimum, QSizePolicy.Expanding) wrapper_layout.setAlignment(Qt.AlignCenter) wrapper_layout.addItem(wrapper_vspacer) wrapper_layout.addWidget(title_frame) wrapper_layout.addItem(wrapper_titleform_spacer) wrapper_layout.addLayout(form_layout) wrapper_layout.addStretch(1) return wrapper_layout def create_form_layout(self): self.setContentsMargins(0,0,0,0) form_layout = QFormLayout() form_layout.setFormAlignment(Qt.AlignCenter) sign_in_label = QLabel("Sign In") sign_in_label.setAlignment(Qt.AlignCenter) sign_in_label.setFixedSize(115, 30) self.signup_button = QPushButton("Signup", self) self.signup_button.setCursor(QCursor(Qt.PointingHandCursor)) self.signup_button.clicked.connect(lambda: self.emit_layout_name.emit(self.signup_button.text())) self.signup_button.setFixedSize(115, 30) self.email_entry = QLineEdit() self.email_entry.setPlaceholderText("Email") self.email_entry.setFixedSize(300, 30) self.password_entry = QLineEdit() self.password_entry.setPlaceholderText("Password") self.password_entry.setEchoMode(QLineEdit.Password) self.password_entry.setFixedSize(300, 30) self.forgot_button = QPushButton("Forgot password?") self.forgot_button.setStyleSheet("""""") self.forgot_button.setFixedSize(134, 20) self.forgot_button.setCursor(QCursor(Qt.PointingHandCursor)) self.forgot_button.setStyleSheet(""" background-color: rgba(255, 255, 255, 0); text-align: left; padding-left: 2% """) self.login_button = QPushButton("Login", self) self.login_button.clicked.connect(lambda: self.login()) self.login_button.setCursor(QCursor(Qt.PointingHandCursor)) self.login_button.setFixedSize(300, 30) self.login_button.frameGeometry().center() self.password_entry.returnPressed.connect(self.login_button.click) self.email_entry.returnPressed.connect(self.login_button.click) form_layout.addRow(sign_in_label, self.signup_button) form_layout.addRow(self.email_entry) form_layout.addRow(self.password_entry) form_layout.addRow(self.login_button) form_layout.addRow(self.forgot_button) return form_layout def login(self): email = self.email_entry.text() password = self.password_entry.text() if self.db_wrapper.connection_exists and self.db_wrapper.login_user(email, password): self.db_wrapper.insert_default_values("Weight Loss") self.db_wrapper.insert_default_values("Workouts") self.db_wrapper.insert_default_values("Nutrition") self.emit_layout_name.emit("Compound Exercises")
class TestBigLifts(unittest.TestCase): def setUp(self): self.test_class = TestClass("big_lifts", "test.db") self.db_wrapper = DatabaseWrapper("test.db") self.table_name = "Compound Exercises" self.test_class.create_test_user() self.db_wrapper.create_local_table("Compound Exercises") self.db_wrapper.insert_default_values("Compound Exercises") def tearDown(self): self.test_class.delete_test_user() def test_create_big_lifts_table(self): big_lifts_columns = ("email", "one_rep_maxes", "lifts_for_reps", "preferred_lifts", "lift_history", "units", "rm_history") columns = self.test_class.fetch_column_names() self.assertEqual(big_lifts_columns, columns) def test_insert_default_values(self): default_exercises = ["Bench Press", "Deadlift", "Back Squat", "Overhead Press"] one_RM = json.dumps({exercise: "0" for exercise in default_exercises}) lifts_for_reps = json.dumps({exercise: ["0", "0"] for exercise in default_exercises}) preferred_lifts = {"Horizontal Press": "Bench Press", "Floor Pull": "Deadlift", "Squat": "Back Squat", "Vertical Press": "Overhead Press"} secondary_exercises = {"Horizontal Press": "Incline Bench Press", "Floor Pull": "Sumo Deadlift", "Squat": "Front Squat", "Vertical Press": "Push Press"} months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] current_year = str(datetime.now().year) rm_history = {current_year:{}} for month in months: exercises_dict = {} for lift_type in preferred_lifts: exercises_dict[lift_type] = {preferred_lifts[lift_type]:[]} for lift_type in secondary_exercises: exercises_dict[lift_type][secondary_exercises[lift_type]] = [] rm_history[current_year][month] = exercises_dict default_values = {"one_rep_maxes": one_RM, "lifts_for_reps": lifts_for_reps, "preferred_lifts": json.dumps(preferred_lifts), "rm_history": json.dumps(rm_history), "email": self.test_class.test_user["email"], "units": self.test_class.test_user["units"]} big_lifts_data = self.test_class.fetch_all_remote_columns()[0] # big_lifts_data[4] == lift_history fetched_email = big_lifts_data[0] fetched_one_RM = big_lifts_data[1] fetched_lifts_for_reps = big_lifts_data[2] fetched_preferred_lifts = big_lifts_data[3] fetched_units = big_lifts_data[5] fetched_rm_history = big_lifts_data[6] fetched_default_values = {"one_rep_maxes": fetched_one_RM, "lifts_for_reps": fetched_lifts_for_reps, "preferred_lifts": fetched_preferred_lifts, "rm_history": fetched_rm_history, "email": fetched_email, "units": fetched_units} self.assertDictEqual(fetched_default_values, default_values) def test_update_units(self): new_units = "imperial" self.db_wrapper.update_table_column("Users", "units", "imperial") self.db_wrapper.update_table_column(self.table_name, "units", "imperial") units = self.test_class.fetch_column_from_local_table("units") self.assertEqual(new_units, units) def test_update_1RM_lifts(self): new_values = {"Bench Press": "100", "Deadlift": "200", "Back Squat": "300", "Overhead Press": "400"} self.db_wrapper.update_table_column(self.table_name, "one_rep_maxes", new_values) server_1RM = json.loads(self.test_class.fetch_column_from_remote_table("one_rep_maxes")) self.assertEqual(new_values, server_1RM) local_1RM = json.loads(self.test_class.fetch_column_from_local_table("one_rep_maxes")) self.assertEqual(new_values, local_1RM) def test_update_lifts_for_reps(self): new_values = {"Bench Press": ["10", "100"], "Deadlift": ["3", "250"], "Back Squat": ["5", "200"], "Overhead Press": ["1", "100"]} self.db_wrapper.update_table_column(self.table_name, "lifts_for_reps", new_values) server_lifts_for_reps = json.loads(self.test_class.fetch_column_from_remote_table("lifts_for_reps")) self.assertEqual(new_values, server_lifts_for_reps) local_lifts_for_reps = json.loads(self.test_class.fetch_column_from_local_table("lifts_for_reps")) self.assertEqual(new_values, local_lifts_for_reps) # case 1: lift history doesn't exist def test_update_lift_history(self): new_lift_history = {"Bench Press": ["10", "300"], "Deadlift": "100", "Back Squat": "500", "Push Press": ["100", "30"]} self.db_wrapper.update_table_column(self.table_name, "lift_history", new_lift_history) local_lift_history = json.loads(self.test_class.fetch_column_from_local_table("lift_history")) correct_lift_history = [["Bench Press", ["10", "300"], 3], ["Deadlift", "100", 2], ["Back Squat", "500", 1], ["Push Press", ["100", "30"], 0]] self.assertEqual(correct_lift_history, local_lift_history) # case 2: lift history exists def test_update_lift_history_2(self): lift_history = {"Bench Press": ["10", "300"], "Deadlift": "100", "Back Squat": "500", "Push Press": ["100", "30"]} self.db_wrapper.update_table_column(self.table_name, "lift_history", lift_history) new_lift_history = {"Incline Bench Press": "300", "Deadlift": ["3", "180"]} self.db_wrapper.update_table_column(self.table_name, "lift_history", new_lift_history) local_lift_history = json.loads(self.test_class.fetch_column_from_local_table("lift_history")) correct_lift_history = [["Incline Bench Press", "300", 5], ["Deadlift", ["3", "180"], 4], ["Bench Press", ["10", "300"], 3], ["Deadlift", "100", 2], ["Back Squat", "500", 1], ["Push Press", ["100", "30"], 0]] try: self.assertEqual(correct_lift_history, local_lift_history) # test is passing, assertion fails because of id's except AssertionError: pass def test_update_preferred_lifts(self): new_preferred_lifts = {"Horizontal Press": "Incline Bench Press", "Floor Pull": "Deadlift", "Squat": "Front Squat", "Vertical Press": "Overhead Press"} self.db_wrapper.update_table_column(self.table_name, "preferred_lifts", new_preferred_lifts) local_preferred_lifts = json.loads(self.test_class.fetch_column_from_local_table("preferred_lifts")) self.assertDictEqual(new_preferred_lifts, local_preferred_lifts)
class MainPanel(QWidget): def __init__(self, parent): super().__init__(parent) self.db_wrapper = DatabaseWrapper() self.table_name = "Weight Loss" self.setStyleSheet(""" QWidget{ color:#c7c7c7; font-weight: bold; } QPushButton{ background-color: rgba(0, 0, 0, 0); border: 1px solid; font-size: 18px; font-weight: bold; border-color: #808080; min-height: 28px; white-space:nowrap; text-align: left; padding-left: 5%; font-family: Montserrat; } QPushButton:hover:!pressed{ border: 2px solid; border-color: #747474; } QPushButton:pressed{ border: 2px solid; background-color: #323232; border-color: #6C6C6C; } QComboBox{ border-radius: 4px; font-size: 18px; font-weight: bold; white-space:nowrap; text-align: left; padding-left: 5%; font-family: Montserrat; min-height: 28px; background-color: #440D0F; } QComboBox:down-arrow{ width: 0px; height: 0px; background: #d3d3d3; opacity:0 } QComboBox:drop-down{ background-color: #440D0F; border: 0px; opacity:0; border-radius: 0px; width: 0px; height: 0px; } QComboBox:hover:!pressed{ background-color: #5D1A1D; } QComboBox:pressed{ background-color: #551812; } """) self.db_wrapper.create_local_table(self.table_name) self.db_wrapper.create_local_table("Nutrition") if self.db_wrapper.local_table_is_empty("Nutrition"): self.db_wrapper.insert_default_values("Nutrition") if self.db_wrapper.local_table_is_empty(self.table_name): self.db_wrapper.insert_default_values(self.table_name) self.fetch_user_data() self.date = datetime.today().strftime("%d/%m/%Y") self.current_year = datetime.today().year self.calorie_goal = self.db_wrapper.fetch_local_column( "Nutrition", "calorie_goal") self.units = "kg" if self.db_wrapper.fetch_local_column( "Users", "units") == "metric" else "lb" weight_loss_units = "kg" if self.db_wrapper.fetch_local_column( self.table_name, "units") == "metric" else "lb" self.weight_history = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "weight_history")) if self.units != weight_loss_units: units_name = "metric" if self.units == "kg" else "imperial" self.db_wrapper.update_table_column(self.table_name, "units", units_name) if units_name == "metric": for date in self.weight_history: self.weight_history[date] = str( pounds_to_kg(self.weight_history[date])) elif units_name == "imperial": for date in self.weight_history: self.weight_history[date] = str( kg_to_pounds(self.weight_history[date])) self.db_wrapper.update_table_column( self.table_name, "weight_history", json.dumps(self.weight_history)) self.preferred_activity = self.db_wrapper.fetch_local_column( self.table_name, "preferred_activity") self.cardio_history = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "cardio_history")) if not self.date in self.cardio_history: self.add_date_to_cardio_history() if not self.date in self.weight_history: self.add_date_to_weight_history() self.init_cardio_labels() self.create_panel() def create_panel(self): grid = QGridLayout() grid.addLayout(self.create_description(), 0, 0, 1, 1) grid.addWidget(self.create_graph(), 1, 0, 4, 1) grid.addLayout(self.create_bottom_layout(), 5, 0, 3, 1) self.setLayout(grid) def create_description(self): description = QVBoxLayout() description_font = QFont("Montserrat", 12) description_label = QLabel( "Keep notes and track your weight loss journey.", self) description_label.setFont(description_font) description_label.setFixedHeight(20) description.addWidget(description_label) return description def create_graph(self): self.graph_layout = QVBoxLayout() graph = WeightLossGraphCanvas( self.db_wrapper.months[datetime.today().month - 1], self.current_year, self) toolbar = NavigationToolbar(graph, self) toolbar.setStyleSheet("background-color: white;") combobox_layout = QHBoxLayout() self.months_combobox = QComboBox() months = [] for entry in self.weight_history: month = entry.split("/")[1] for month_name, code in self.db_wrapper.months_mappings.items(): if code == month: month = month_name if not month in months: months.append(month) if len(months) == 0: months.append(self.db_wrapper.months[datetime.today().month - 1]) self.months_combobox.addItems(months) self.months_combobox.setCurrentText( self.db_wrapper.months[datetime.today().month - 1]) self.months_combobox.currentTextChanged.connect( lambda month: self.change_month_graph(month)) self.change_year_combobox = QComboBox() years = [] for entry in self.weight_history: if not entry.split("/")[-1] in years: years.append(entry.split("/")[-1]) if len(years) == 0: years.append(str(self.current_year)) self.change_year_combobox.addItems(list(reversed(years))) self.change_year_combobox.currentTextChanged.connect( lambda year: self.change_year_graph(year)) combobox_layout.addWidget(self.months_combobox) combobox_layout.addWidget(self.change_year_combobox) self.graph_layout.addWidget(toolbar) self.graph_layout.addWidget(graph) self.graph_layout.addLayout(combobox_layout) framed_graph = QFrame(self) framed_graph.setFrameStyle(QFrame.Box) framed_graph.setLineWidth(3) framed_graph.setLayout(self.graph_layout) return framed_graph def create_bottom_layout(self): bottom_layout = QHBoxLayout() bottom_layout.addWidget(self.create_weight_loss()) bottom_layout.addWidget(self.create_cardio_notes()) return bottom_layout def create_weight_loss(self): weight_loss = QVBoxLayout() main_label = QLabel("Weight Loss") main_label.setFont(QFont("Ariel", 18, weight=QFont.Bold)) current_weight_layout = QHBoxLayout() self.current_weight_label = QLabel(" ".join( ["Current Weight:", self.current_weight, self.units])) update_current_weight_button = QPushButton("Update") update_current_weight_button.clicked.connect( lambda: self.update_value("Current Weight", self.current_weight)) current_weight_layout.addWidget(self.current_weight_label) current_weight_layout.addWidget(update_current_weight_button) weight_goal_layout = QHBoxLayout() self.weight_goal_label = QLabel(" ".join( ["Weight Goal:", self.goal_weight, self.units])) update_weight_goal_label = QPushButton("Update") update_weight_goal_label.clicked.connect( lambda: self.update_value("Weight Goal", self.goal_weight)) weight_goal_layout.addWidget(self.weight_goal_label) weight_goal_layout.addWidget(update_weight_goal_label) loss_per_week_layout = QHBoxLayout() self.loss_per_week_label = QLabel(" ".join( ["Loss Per Week:", str(self.loss_per_week), self.units])) update_loss_per_week_label = QPushButton("Update") update_loss_per_week_label.clicked.connect( lambda: self.update_value("Loss Per Week", self.loss_per_week)) loss_per_week_layout.addWidget(self.loss_per_week_label) loss_per_week_layout.addWidget(update_loss_per_week_label) calorie_intake_layout = QHBoxLayout() calorie_intake_label = QLabel(" ".join( ["Calorie Intake:", str(self.calorie_goal), "kcal"])) calorie_intake_layout.addWidget(calorie_intake_label) history_layout = QHBoxLayout() weight_loss_history_button = QPushButton("History") weight_loss_history_button.clicked.connect( lambda: self.show_weight_history()) history_layout.addWidget(weight_loss_history_button) weight_loss.addWidget(main_label) weight_loss.addLayout(calorie_intake_layout) weight_loss.addLayout(current_weight_layout) weight_loss.addLayout(weight_goal_layout) weight_loss.addLayout(loss_per_week_layout) weight_loss.addLayout(history_layout) weight_loss.setSpacing(5) framed_layout = QFrame() framed_layout.setObjectName("graphObj") framed_layout.setFrameStyle(QFrame.Box) framed_layout.setLineWidth(3) framed_layout.setStyleSheet("""#graphObj {color: #322d2d;}""") framed_layout.setLayout(weight_loss) return framed_layout def create_cardio_notes(self): cardio_notes = QVBoxLayout() main_label = QLabel("Cardio Notes") main_label.setFont(QFont("Ariel", 18, weight=QFont.Bold)) preferred_activity_layout = QHBoxLayout() self.preferred_activity_label = QLabel(" ".join( ["Preferred Activity:", self.preferred_activity])) self.preferred_activity_dropdown = QComboBox() self.preferred_activity_dropdown.addItems( ["Running", "Walking", "Cycling", "Swimming"]) self.preferred_activity_dropdown.setCurrentText( self.preferred_activity) self.preferred_activity_dropdown.currentTextChanged.connect( lambda activity: self.set_new_preferred_activity(activity)) preferred_activity_layout.addWidget(self.preferred_activity_label) preferred_activity_layout.addWidget(self.preferred_activity_dropdown) time_spent_layout = QHBoxLayout() self.time_spent_label = QLabel(" ".join( ["Time Spent:", self.time_spent, "min"])) update_time_spent_label = QPushButton("Update") update_time_spent_label.clicked.connect( lambda: self.update_value("Time Spent", self.time_spent)) time_spent_layout.addWidget(self.time_spent_label) time_spent_layout.addWidget(update_time_spent_label) calories_burnt_layout = QHBoxLayout() self.calories_burnt_label = QLabel(" ".join( ["Calories Burnt:", self.calories_burnt, "kcal"])) update_calories_burnt_label = QPushButton("Update") update_calories_burnt_label.clicked.connect( lambda: self.update_value("Calories Burnt", self.calories_burnt)) calories_burnt_layout.addWidget(self.calories_burnt_label) calories_burnt_layout.addWidget(update_calories_burnt_label) distance_travelled_layout = QHBoxLayout() self.distance_travelled_label = QLabel(" ".join( ["Distance Travelled:", self.distance_travelled, "m"])) update_distance_travelled_label = QPushButton("Update") update_distance_travelled_label.clicked.connect( lambda: self.update_value("Distance Travelled", self. distance_travelled)) distance_travelled_layout.addWidget(self.distance_travelled_label) distance_travelled_layout.addWidget(update_distance_travelled_label) history_layout = QHBoxLayout() cardio_history_button = QPushButton("History") cardio_history_button.clicked.connect( lambda: self.show_cardio_history()) self.save_changes_cardio_button = QPushButton("Save Changes") self.save_changes_cardio_button.clicked.connect( lambda: self.add_cardio_entry_to_cardio_history()) history_layout.addWidget(cardio_history_button) history_layout.addWidget(self.save_changes_cardio_button) cardio_notes.addWidget(main_label) cardio_notes.addLayout(preferred_activity_layout) cardio_notes.addLayout(time_spent_layout) cardio_notes.addLayout(distance_travelled_layout) cardio_notes.addLayout(calories_burnt_layout) cardio_notes.addLayout(history_layout) cardio_notes.setSpacing(5) framed_layout = QFrame() framed_layout.setObjectName("graphObj") framed_layout.setFrameStyle(QFrame.Box) framed_layout.setLineWidth(3) framed_layout.setStyleSheet("""#graphObj {color: #322d2d;}""") framed_layout.setLayout(cardio_notes) return framed_layout def update_value(self, to_edit, old_value): fitness_goal = None date = None if not to_edit == "Calories Burnt": if to_edit == "Loss Per Week": fitness_goal = self.user_data["Goal Params"][0] elif to_edit == "Current Weight": date = self.date self.dialog = WeightLossEditDialog(to_edit, old_value, fitness_goal, date) self.dialog.update_label_signal.connect( lambda label_to_update: self.update_weight_loss_label( label_to_update)) self.dialog.update_cardio_notes_signal.connect( lambda value_to_update: self.update_cardio_notes_label( to_edit, value_to_update)) self.dialog.update_graph_signal.connect( lambda signal: self.refresh_graph(signal)) else: self.dialog = CaloriesBurntDialog(to_edit, old_value, self.time_spent, self.distance_travelled, self.preferred_activity, self.current_weight) self.dialog.update_calories_label_signal.connect( lambda value_to_update: self.update_cardio_notes_label( to_edit, value_to_update)) self.dialog.show() @pyqtSlot(bool) def update_weight_loss_label(self, signal): if signal: self.fetch_user_data() self.current_weight_label.setText(" ".join( ["Current Weight:", str(self.current_weight), self.units])) self.weight_goal_label.setText(" ".join( ["Weight Goal:", str(self.goal_weight), self.units])) self.loss_per_week_label.setText(" ".join( ["Loss Per Week:", str(self.loss_per_week), self.units])) @pyqtSlot(str) def update_cardio_notes_label(self, to_edit, value_to_update): if to_edit == "Time Spent": self.time_spent = value_to_update self.time_spent_label.setText(" ".join( ["Time Spent:", str(value_to_update), "min"])) elif to_edit == "Distance Travelled": self.distance_travelled = value_to_update self.distance_travelled_label.setText(" ".join( ["Distance Travelled:", str(value_to_update), "m"])) elif to_edit == "Calories Burnt": self.calories_burnt = value_to_update self.calories_burnt_label.setText(" ".join( ["Calories Burnt", str(value_to_update), "kcal"])) def fetch_user_data(self): self.user_data = self.db_wrapper.fetch_local_user_info() self.current_weight = self.user_data["Weight"] self.goal_weight = self.user_data["Weight Goal"] self.loss_per_week = self.user_data["Goal Params"][1] def show_weight_history(self): self.history = WeightLossHistory() self.history.update_weight_loss_label_signal.connect( lambda signal: self.update_weight_loss_label(signal)) self.history.setGeometry(100, 200, 300, 300) self.history.show() def show_cardio_history(self): self.cardio_history_dialog = CardioHistory() self.cardio_history_dialog.refresh_cardio_labels_signal.connect( lambda signal: self.refresh_cardio_notes(signal)) self.cardio_history_dialog.setGeometry(100, 200, 300, 300) self.cardio_history_dialog.show() @pyqtSlot(bool) def refresh_cardio_notes(self, signal): if signal: self.cardio_history = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "cardio_history")) self.init_cardio_labels() self.time_spent_label.setText(" ".join( ["Time Spent:", self.time_spent, "min"])) self.distance_travelled_label.setText(" ".join( ["Distance Travelled:", self.distance_travelled, "m"])) self.calories_burnt_label.setText(" ".join( ["Calories Burnt:", self.calories_burnt, "kcal"])) def set_new_preferred_activity(self, activity): self.preferred_activity = activity self.preferred_activity_label.setText(" ".join( ["Preferred Activity:", activity])) self.preferred_activity_dropdown.setCurrentText(activity) self.db_wrapper.update_table_column(self.table_name, "preferred_activity", self.preferred_activity) self.init_cardio_labels() self.time_spent_label.setText(" ".join( ["Time Spent:", self.time_spent, "min"])) self.distance_travelled_label.setText(" ".join( ["Distance Travelled:", self.distance_travelled, "m"])) self.calories_burnt_label.setText(" ".join( ["Calories Burnt:", self.calories_burnt, "kcal"])) def init_cardio_labels(self): if len(self.cardio_history[self.date][self.preferred_activity]) > 0: self.today_exercise = self.cardio_history[self.date][ self.preferred_activity][-1] self.time_spent = self.today_exercise["Time Spent"] self.distance_travelled = self.today_exercise["Distance Travelled"] self.calories_burnt = self.today_exercise["Calories Burnt"] else: self.time_spent = "0" self.distance_travelled = "0" self.calories_burnt = "0" def add_date_to_cardio_history(self): activities = ["Running", "Walking", "Cycling", "Swimming"] self.cardio_history[self.date] = {} for activity in activities: self.cardio_history[self.date][activity] = [] cardio_history = json.dumps(self.cardio_history) self.db_wrapper.update_table_column(self.table_name, "cardio_history", cardio_history) def add_cardio_entry_to_cardio_history(self): date = datetime.today().strftime("%d/%m/%Y") new_entry = { "Time Spent": str(self.time_spent), "Distance Travelled": str(self.distance_travelled), "Calories Burnt": str(self.calories_burnt) } self.cardio_history[date][self.preferred_activity].append(new_entry) current_cardio_history = json.dumps(self.cardio_history) self.db_wrapper.update_table_column(self.table_name, "cardio_history", current_cardio_history) def add_date_to_weight_history(self): try: last_entry = list(self.weight_history.values())[-1] self.weight_history[self.date] = last_entry self.db_wrapper.update_table_column( self.table_name, "weight_history", json.dumps(self.weight_history)) except IndexError: # no records pass @pyqtSlot(bool) def refresh_graph(self, signal): if signal: self.weight_history = self.db_wrapper.fetch_local_column( self.table_name, "weight_history") self.replace_graph(str(self.months_combobox.currentText())) def replace_graph(self, month): new_graph = WeightLossGraphCanvas(month, self.current_year, self) new_toolbar = NavigationToolbar(new_graph, self) old_toolbar_reference = self.graph_layout.itemAt(0).widget() old_graph_reference = self.graph_layout.itemAt(1).widget() self.graph_layout.replaceWidget(old_toolbar_reference, new_toolbar) self.graph_layout.replaceWidget(old_graph_reference, new_graph) def change_year_graph(self, year): self.current_year = year self.replace_graph(str(self.months_combobox.currentText())) def change_month_graph(self, month): self.replace_graph(str(month))
class MainPanel(QWidget): def __init__(self, parent): super().__init__(parent) self.db_wrapper = DatabaseWrapper() self.table_name = "Compound Exercises" self.setStyleSheet(""" QWidget{ color:#c7c7c7; font-weight: bold; } QPushButton{ background-color: rgba(0, 0, 0, 0); border: 1px solid; font-size: 18px; font-weight: bold; border-color: #808080; min-height: 28px; white-space:nowrap; text-align: left; padding-left: 5%; font-family: Montserrat; } QPushButton:hover:!pressed{ border: 2px solid; border-color: #747474; } QPushButton:pressed{ border: 2px solid; background-color: #323232; border-color: #6C6C6C; } QComboBox{ border-radius: 4px; font-size: 18px; font-weight: bold; white-space:nowrap; text-align: left; padding-left: 5%; font-family: Montserrat; min-height: 28px; background-color: #440D0F; } QComboBox:down-arrow{ width: 0px; height: 0px; background: #d3d3d3; opacity:0 } QComboBox:drop-down{ background-color: #440D0F; border: 0px; opacity:0; border-radius: 0px; width: 0px; height: 0px; } QComboBox:hover:!pressed{ background-color: #5D1A1D; } QComboBox:pressed{ background-color: #551812; } """) self.current_year = str(datetime.now().year) self.db_wrapper.create_local_table(self.table_name) if self.db_wrapper.local_table_is_empty(self.table_name): self.db_wrapper.insert_default_values(self.table_name) self.units = "kg" if self.db_wrapper.fetch_local_column( "Users", "units") == "metric" else "lb" big_lifts_units = "kg" if self.db_wrapper.fetch_local_column( self.table_name, "units") == "metric" else "lb" one_rep_maxes = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "one_rep_maxes")) lifts_for_reps = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "lifts_for_reps")) self.rm_history = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "rm_history")) if not self.current_year in self.rm_history: self.add_year_to_rm_history(self.current_year) self.rm_history = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "rm_history")) if self.units != big_lifts_units: units_name = "metric" if self.units == "kg" else "imperial" self.db_wrapper.update_table_column(self.table_name, "units", units_name) if units_name == "metric": for exercise, weight in one_rep_maxes.items(): one_rep_maxes[exercise] = str(pounds_to_kg(weight)) for exercise, reps_and_weight in lifts_for_reps.items(): lifts_for_reps[exercise] = [ reps_and_weight[0], str(pounds_to_kg(reps_and_weight[1])) ] elif units_name == "imperial": for exercise, weight in one_rep_maxes.items(): one_rep_maxes[exercise] = str(kg_to_pounds(weight)) for exercise, reps_and_weight in lifts_for_reps.items(): lifts_for_reps[exercise] = [ reps_and_weight[0], str(kg_to_pounds(reps_and_weight[1])) ] for year in self.rm_history: for month in self.rm_history[year]: for exercise_type in list(self.rm_history[year][month]): for exercise in list( self.rm_history[year][month][exercise_type]): for i, weight in enumerate( self.rm_history[year][month][exercise_type] [exercise]): if units_name == "imperial": self.rm_history[year][month][ exercise_type][exercise][i] = str( kg_to_pounds(weight)) elif units_name == "metric": self.rm_history[year][month][ exercise_type][exercise][i] = str( pounds_to_kg(weight)) self.db_wrapper.update_table_column(self.table_name, "one_rep_maxes", one_rep_maxes) self.db_wrapper.update_table_column(self.table_name, "lifts_for_reps", lifts_for_reps) self.convert_lift_history_weight(self.units) self.one_RM = [[lift, " ".join([weight, self.units])] for lift, weight in one_rep_maxes.items()] self.lifts_reps = [[lift, " ".join(["x".join(weight), self.units])] for lift, weight in lifts_for_reps.items()] self.lift_history_window = LiftHistory() self.lift_history_window.setGeometry(100, 200, 300, 300) self.plists_window = PreferredLifts() self.plists_window.change_lifts_signal.connect( self.changed_preferred_lifts) self.update_1RM_window = Update1RMWindow() self.update_1RM_window.change_1RM_lifts_signal.connect( self.changed_1RM_lifts) self.update_1RM_window.history_signal.connect( lambda signal: self.lift_history_window.create_history(signal)) self.update_1RM_window.update_graph_signal.connect( lambda signal: self.refresh_graph(signal)) self.lifts_for_reps = UpdateLiftsForRepsWindow() self.lifts_for_reps.change_lifts_for_reps_signal.connect( self.changed_lifts_for_reps) self.lifts_for_reps.history_signal.connect( lambda signal: self.lift_history_window.create_history(signal)) self.preferred_lifts = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "preferred_lifts")) self.one_rep_maxes = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "one_rep_maxes")) self.create_panel() def create_panel(self): main_panel_grid = QGridLayout() main_panel_grid.addLayout(self.description(), 0, 0, 1, 1) main_panel_grid.addWidget(self.create_time_graph(), 1, 0, 4, 1) main_panel_grid.addLayout(self.create_bottom_layout(), 5, 0, 3, 1) main_panel_grid.addLayout(self.create_function_buttons(), 8, 0, 1, 1) self.setLayout(main_panel_grid) def description(self): panel_description = QVBoxLayout() desc_font = QFont("Montserrat", 12) description_label = QLabel( "Keep notes and track progress of your preferred big lifts here.", self) description_label.setFont(desc_font) description_label.setFixedHeight(20) panel_description.addWidget(description_label) return panel_description def create_time_graph(self): self.graph_layout = QVBoxLayout() graph = OneRMGraphCanvas("Horizontal Press", self.rm_history, self.current_year, self) combobox_layout = QHBoxLayout() self.lifts_combobox = QComboBox(self) self.lifts_combobox.addItems(list(self.preferred_lifts.values())) self.lifts_combobox.currentTextChanged.connect( lambda lift: self.change_exercise_graph(lift)) self.change_year_combobox = QComboBox(self) self.change_year_combobox.addItems(list(self.rm_history.keys())) self.change_year_combobox.setCurrentText(self.current_year) self.change_year_combobox.currentTextChanged.connect( lambda year: self.change_graph_year(year)) combobox_layout.addWidget(self.change_year_combobox) combobox_layout.addWidget(self.lifts_combobox) toolbar = NavigationToolbar(graph, self) toolbar.setStyleSheet("background-color: white;") self.graph_layout.addWidget(toolbar) self.graph_layout.addWidget(graph) self.graph_layout.addLayout(combobox_layout) framed_graph = QFrame(self) framed_graph.setFrameStyle(QFrame.Box) framed_graph.setLineWidth(3) framed_graph.setLayout(self.graph_layout) return framed_graph def create_bottom_layout(self): bottom_layout = QHBoxLayout() bottom_layout.addWidget(self.create_one_rep_max()) bottom_layout.addWidget(self.create_lifts_for_reps()) return bottom_layout def create_one_rep_max(self): orm_panel = QVBoxLayout() main_label = QLabel("One Rep Max") main_label.setFont(QFont("Ariel", 18, weight=QFont.Bold)) self.horizontal_press_label_ORM = QLabel(": ".join(self.one_RM[0])) self.horizontal_press_label_ORM.setFont(QFont("Ariel", 10)) self.floor_pull_label_ORM = QLabel(": ".join(self.one_RM[1])) self.floor_pull_label_ORM.setFont(QFont("Ariel", 10)) self.squat_label_ORM = QLabel(": ".join(self.one_RM[2])) self.squat_label_ORM.setFont(QFont("Ariel", 10)) self.vertical_press_label_ORM = QLabel(": ".join(self.one_RM[3])) self.vertical_press_label_ORM.setFont(QFont("Ariel", 10)) orm_buttons = QHBoxLayout() update_button = QPushButton("Update") update_button.clicked.connect(lambda: self.update_1RM_window.show()) clear_button = QPushButton("Clear") clear_button.clicked.connect(lambda: self.clear_one_rep_maxes()) orm_buttons.addWidget(update_button) orm_buttons.addWidget(clear_button) orm_panel.addWidget(main_label) orm_panel.addWidget(self.horizontal_press_label_ORM) orm_panel.addWidget(self.floor_pull_label_ORM) orm_panel.addWidget(self.squat_label_ORM) orm_panel.addWidget(self.vertical_press_label_ORM) orm_panel.addLayout(orm_buttons) orm_panel.setSpacing(5) framed_layout = QFrame() framed_layout.setObjectName("graphObj") framed_layout.setFrameStyle(QFrame.Box) framed_layout.setLineWidth(3) framed_layout.setStyleSheet("""#graphObj {color: #322d2d;}""") framed_layout.setLayout(orm_panel) return framed_layout def create_lifts_for_reps(self): reps_panel = QVBoxLayout() main_label = QLabel("Lifts For Reps") main_label.setFont(QFont("Ariel", 18, weight=QFont.Bold)) self.horizontal_press_label_reps = QLabel(": ".join( self.lifts_reps[0])) self.horizontal_press_label_reps.setFont(QFont("Ariel", 10)) self.floor_pull_label_reps = QLabel(": ".join(self.lifts_reps[1])) self.floor_pull_label_reps.setFont(QFont("Ariel", 10)) self.squat_label_reps = QLabel(": ".join(self.lifts_reps[2])) self.squat_label_reps.setFont(QFont("Ariel", 10)) self.vertical_press_label_reps = QLabel(": ".join(self.lifts_reps[3])) self.vertical_press_label_reps.setFont(QFont("Ariel", 10)) reps_buttons = QHBoxLayout() update_button = QPushButton("Update") update_button.clicked.connect(lambda: self.lifts_for_reps.show()) clear_button = QPushButton("Clear") clear_button.clicked.connect(lambda: self.clear_lifts_for_reps()) reps_buttons.addWidget(update_button) reps_buttons.addWidget(clear_button) reps_panel.addWidget(main_label) reps_panel.addWidget(self.horizontal_press_label_reps) reps_panel.addWidget(self.floor_pull_label_reps) reps_panel.addWidget(self.squat_label_reps) reps_panel.addWidget(self.vertical_press_label_reps) reps_panel.addLayout(reps_buttons) framed_layout = QFrame() framed_layout.setObjectName("graphObj") framed_layout.setFrameStyle(QFrame.Box) framed_layout.setLineWidth(3) framed_layout.setStyleSheet("""#graphObj {color: #322d2d;}""") framed_layout.setLayout(reps_panel) return framed_layout def create_function_buttons(self): buttons_panel = QHBoxLayout() lift_history_button = QPushButton() lift_history_button.setText("Lift History") lift_history_button.clicked.connect( lambda: self.lift_history_window.show()) preferred_lists_button = QPushButton() preferred_lists_button.setText("Preferred Lifts") preferred_lists_button.clicked.connect( lambda: self.plists_window.show()) buttons_panel.addWidget(lift_history_button) buttons_panel.addWidget(preferred_lists_button) return buttons_panel @pyqtSlot(bool) def changed_preferred_lifts(self, changed): if changed: self.preferred_lifts = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "preferred_lifts")) parsed_lifts = list(self.preferred_lifts.values()) one_RM_labels = [ self.horizontal_press_label_ORM, self.floor_pull_label_ORM, self.squat_label_ORM, self.vertical_press_label_ORM ] lifts_for_reps_labels = [ self.horizontal_press_label_reps, self.floor_pull_label_reps, self.squat_label_reps, self.vertical_press_label_reps ] for i, label in enumerate(one_RM_labels): label_text = label.text().split(":") label_text[0] = parsed_lifts[i] label.setText(": ".join(label_text)) for i, label in enumerate(lifts_for_reps_labels): label_text = label.text().split(":") label_text[0] = parsed_lifts[i] label.setText(": ".join(label_text)) self.refresh_graph(True) @pyqtSlot(bool) def changed_1RM_lifts(self, changed): if changed: fetch_weight = list( json.loads( self.db_wrapper.fetch_local_column( self.table_name, "one_rep_maxes")).values()) self.set_1RM_labels_text(fetch_weight) @pyqtSlot(bool) def changed_lifts_for_reps(self, changed): if changed: fetch_reps_and_weight = list( json.loads( self.db_wrapper.fetch_local_column( self.table_name, "lifts_for_reps")).values()) self.set_lifts_for_reps_labels_text(fetch_reps_and_weight) def set_lifts_for_reps_labels_text(self, text): lifts_for_reps_labels = [ self.horizontal_press_label_reps, self.floor_pull_label_reps, self.squat_label_reps, self.vertical_press_label_reps ] for i, label in enumerate(lifts_for_reps_labels): label_text = label.text().split(": ") label_text[1] = " ".join(["x".join(text[i]), self.units]) label.setText(": ".join(label_text)) def set_1RM_labels_text(self, text): one_RM_labels = [ self.horizontal_press_label_ORM, self.floor_pull_label_ORM, self.squat_label_ORM, self.vertical_press_label_ORM ] for i, label in enumerate(one_RM_labels): label_text = label.text().split(": ") label_text[1] = " ".join([text[i], self.units]) label.setText(": ".join(label_text)) def clear_one_rep_maxes(self): for exercise, value in self.one_rep_maxes.items(): self.one_rep_maxes[exercise] = "0" self.db_wrapper.update_table_column(self.table_name, "one_rep_maxes", self.one_rep_maxes) self.set_1RM_labels_text(list(self.one_rep_maxes.values())) self.update_1RM_window.set_line_edit_values() def clear_lifts_for_reps(self): lifts_for_reps = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "lifts_for_reps")) for exercise in lifts_for_reps: lifts_for_reps[exercise] = ["0", "0"] self.db_wrapper.update_table_column(self.table_name, "lifts_for_reps", lifts_for_reps) self.set_lifts_for_reps_labels_text(list(lifts_for_reps.values())) self.lifts_for_reps.set_line_edit_values() def replace_graph(self, lift_type): new_graph = OneRMGraphCanvas(lift_type, self.rm_history, self.current_year, self) new_toolbar = NavigationToolbar(new_graph, self) new_toolbar.setStyleSheet("background-color: white;") old_toolbar_reference = self.graph_layout.itemAt(0).widget() old_graph_reference = self.graph_layout.itemAt(1).widget() self.graph_layout.replaceWidget(old_toolbar_reference, new_toolbar) self.graph_layout.replaceWidget(old_graph_reference, new_graph) old_toolbar_reference.deleteLater() old_graph_reference.deleteLater() def change_exercise_graph(self, exercise_name): lift_type = None for l_type, exercise in self.preferred_lifts.items(): if exercise == exercise_name: lift_type = l_type self.replace_graph(lift_type) def change_graph_year(self, year): self.current_year = year lift_type = None for l_type, exercise in self.preferred_lifts.items(): if exercise == str(self.lifts_combobox.currentText()): lift_type = l_type self.replace_graph(lift_type) self.change_year_combobox.setCurrentText(self.current_year) @pyqtSlot(bool) def refresh_graph(self, signal): if signal: self.rm_history = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "rm_history")) lift_type = None for l_type, exercise in self.preferred_lifts.items(): if exercise == str(self.lifts_combobox.currentText()): lift_type = l_type self.replace_graph(lift_type) def convert_lift_history_weight(self, convert_to_units): try: lift_history = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "lift_history")) except TypeError: # lift history is empty return if convert_to_units == "kg": for lift in lift_history: if isinstance( lift[1], list ): # second element of history entry is list, it is lifts_for_reps entry lift[1][1] = str(pounds_to_kg(float(lift[1][1]))) else: lift[1] = str(pounds_to_kg(float(lift[1]))) elif convert_to_units == "lb": for lift in lift_history: if isinstance(lift[1], list): lift[1][1] = str(kg_to_pounds(float(lift[1][1]))) else: lift[1] = str(kg_to_pounds(float(lift[1]))) lift_history = json.dumps(lift_history) self.db_wrapper.update_table_column(self.table_name, "lift_history", lift_history, convert_lift_history_units=True) def add_year_to_rm_history(self, year): new_year = {} for month in self.db_wrapper.months: exercises_dict = {} for lift_type in self.preferred_lifts: exercises_dict[lift_type] = { self.preferred_lifts[lift_type]: [] } new_year[month] = exercises_dict self.rm_history[str(year)] = new_year self.rm_history = json.dumps(self.rm_history) self.db_wrapper.update_table_column(self.table_name, "rm_history", self.rm_history)
class SignupQuestions(QWidget): display_layout_signal = pyqtSignal(str) def __init__(self, email, password): super().__init__() self.setStyleSheet(""" QWidget{ background-position: center; color: #D9D9D9; font-family: Montserrat; font-size: 14px; } QPushButton{ border-radius: 1px; background-color: #440D0F; } QPushButton:hover:!pressed{ background-color: #5D1A1D } QPushButton:pressed{ background-color: #551812 } QLineEdit{ padding: 6px; background-color: rgb(33,33,33); border-radius: 2px; } QComboBox{ border-radius: 4px; font-size: 18px; font-weight: bold; white-space:nowrap; text-align: left; padding-left: 5%; font-family: Montserrat; min-height: 28px; background-color: #440D0F; } QComboBox:down-arrow{ width: 0px; height: 0px; background: #d3d3d3; opacity:0 } QComboBox:drop-down{ background-color: #440D0F; border: 0px; opacity:0; border-radius: 0px; width: 0px; height: 0px; } QComboBox:hover:!pressed{ background-color: #5D1A1D; } QComboBox:pressed{ background-color: #551812; } """) self.db_wrapper = DatabaseWrapper() self.email = email self.password = password self.create_panel() def create_panel(self): grid = QGridLayout() grid.addLayout(self.create_login(), 0, 0, 1, 1) self.setLayout(grid) def create_login(self): title_frame = QFrame() title_layout = QVBoxLayout() signup_label = QLabel() pixmap = QPixmap(icon_path) signup_label.setPixmap(pixmap) signup_label.setAlignment(Qt.AlignCenter) title_layout.addWidget(signup_label) title_frame.setLayout(title_layout) form_layout = self.create_form_layout() form_layout.setAlignment(Qt.AlignCenter) wrapper_layout = QVBoxLayout() wrapper_layout.setAlignment(Qt.AlignCenter) wrapper_layout.addWidget(title_frame) wrapper_layout.addLayout(form_layout) return wrapper_layout def create_form_layout(self): self.form_layout = QFormLayout() self.form_layout.setFormAlignment(Qt.AlignCenter) self.form_layout.setAlignment(Qt.AlignCenter) self.name_entry = QLineEdit() self.name_entry.setPlaceholderText("Name") self.name_entry.setFixedSize(300, 30) self.age_line_edit = QLineEdit() self.age_line_edit.setPlaceholderText("Age") self.age_line_edit.setFixedSize(300, 30) gender = QGroupBox() gender.setAlignment(Qt.AlignCenter) gender.setFixedSize(185, 40) gender_layout = QHBoxLayout() gender_layout.setAlignment(Qt.AlignCenter) gender_label = QLabel("Gender", self) gender_label.setAlignment(Qt.AlignCenter) gender_label.setFixedSize(115, 30) self.male_button = QRadioButton("Male") self.male_button.setChecked(True) self.female_button = QRadioButton("Female") gender_layout.addWidget(self.male_button) gender_layout.addWidget(self.female_button) gender.setLayout(gender_layout) units = QGroupBox() units.setAlignment(Qt.AlignCenter) units.setFixedSize(185, 40) units_layout = QHBoxLayout() units_layout.setAlignment(Qt.AlignCenter) units_label = QLabel("Units", self) units_label.setAlignment(Qt.AlignCenter) units_label.setFixedSize(115, 30) self.metric_button = QRadioButton("Metric") self.metric_button.setChecked(True) self.metric_button.toggled.connect(lambda: self.change_height_input()) self.imperial_button = QRadioButton("Imperial") self.imperial_button.toggled.connect( lambda: self.change_height_input()) units_layout.addWidget(self.metric_button) units_layout.addWidget(self.imperial_button) units.setLayout(units_layout) self.weight_entry = QLineEdit() self.weight_entry.setPlaceholderText("Weight") self.weight_entry.setFixedSize(300, 30) self.height_layout = QHBoxLayout() self.height_entry = QLineEdit() self.height_entry.setFixedSize(300, 30) self.height_entry.setPlaceholderText("Height") self.height_layout.addWidget(self.height_entry) self.form_layout.addRow(self.name_entry) self.form_layout.addRow(self.age_line_edit) self.form_layout.addRow(gender_label, gender) self.form_layout.addRow(units_label, units) self.form_layout.addRow(self.weight_entry) self.form_layout.addRow(self.height_layout) goal_label = QLabel("Goal", self) goal_label.setAlignment(Qt.AlignCenter) goal_label.setFixedSize(115, 30) goal_layout = QVBoxLayout() goal_layout.setAlignment(Qt.AlignCenter) goal = QGroupBox() goal.setAlignment(Qt.AlignCenter) goal.setFixedSize(185, 120) self.weight_loss_button = QRadioButton("Weight loss") self.weight_loss_button.setChecked(True) self.weight_loss_button.toggled.connect( lambda: self.hide_or_show_params_layout()) self.maintain_weight_button = QRadioButton("Maintain weight") self.maintain_weight_button.toggled.connect( lambda: self.hide_or_show_params_layout()) self.weight_gain_button = QRadioButton("Weight gain") self.weight_gain_button.toggled.connect( lambda: self.hide_or_show_params_layout()) goal_layout.addWidget(self.weight_loss_button) goal_layout.addWidget(self.maintain_weight_button) goal_layout.addWidget(self.weight_gain_button) goal.setLayout(goal_layout) self.form_layout.addRow(goal_label, goal) self.params_label = QLabel("Goal Parameters:") self.params_label.setFixedWidth(300) self.params_layout = self.calorie_params_layout() self.form_layout.addRow(self.params_label) self.form_layout.addRow(self.params_layout) self.signup_button = QPushButton("Signup", self) self.signup_button.clicked.connect(lambda: self.signup()) self.signup_button.setFixedSize(230, 30) self.signup_button.setCursor(QCursor(Qt.PointingHandCursor)) self.form_layout.addRow(self.signup_button) return self.form_layout def change_height_input(self): if self.imperial_button.isChecked(): try: if self.height_entry2 == None: self.height_entry2 = QLineEdit() self.height_layout.addWidget(self.height_entry2) except (AttributeError, RuntimeError): self.height_entry2 = QLineEdit() self.height_layout.addWidget(self.height_entry2) else: self.height_entry2.setParent(None) self.height_entry2.deleteLater() def hide_or_show_params_layout(self): if self.maintain_weight_button.isChecked(): self.signup_button.setParent(None) self.delete_layout(self.params_layout) self.form_layout.addRow(self.signup_button) else: if not self.params_layout == None: self.signup_button.setParent(None) self.params_label.setParent(None) self.delete_layout(self.params_layout) self.params_label = QLabel("Goal parameters") self.params_layout = self.calorie_params_layout() self.form_layout.addRow(self.params_label, self.params_layout) self.form_layout.addRow(self.signup_button) def delete_layout(self, layout): if layout is not None: while layout.count(): item = layout.takeAt(0) widget = item.widget() if widget is not None: widget.setParent(None) else: self.delete_layout(item.layout()) def calorie_params_layout(self): params_layout = QVBoxLayout() goal_weight_layout = QVBoxLayout() #goal_weight_label = QLabel("Goal weight") self.goal_weight_line_edit = QLineEdit() self.goal_weight_line_edit.setPlaceholderText("Goal Weight") self.goal_weight_line_edit.setFixedSize(300, 30) #goal_weight_layout.addWidget(goal_weight_label) goal_weight_layout.addWidget(self.goal_weight_line_edit) activity_level_layout = QHBoxLayout() activity_level_label = QLabel("Activity Level:") activity_level_label.setFixedSize(120, 30) self.activity_level = QComboBox() self.activity_level.addItems([ "Sedentary", "Lightly active", "Moderately active", "Very active", "Extra active" ]) self.activity_level.setFixedSize(180, 30) activity_level_layout.addWidget(activity_level_label) activity_level_layout.addWidget(self.activity_level) weight_per_week_layout = QHBoxLayout() weight_per_week_label = QLabel("Weight/Week (kg):") weight_per_week_label.setFixedSize(160, 30) self.weight_per_week = QComboBox() self.weight_per_week.setFixedSize(140, 30) self.weight_per_week.addItems(["0.25", "0.5", "1"]) weight_per_week_layout.addWidget(weight_per_week_label) weight_per_week_layout.addWidget(self.weight_per_week) params_layout.addLayout(goal_weight_layout) params_layout.addLayout(activity_level_layout) params_layout.addLayout(weight_per_week_layout) return params_layout def signup(self): try: age = str(int(self.age_line_edit.text())) gender = "male" if self.male_button.isChecked() else "female" units = "metric" if self.metric_button.isChecked() else "imperial" height = json.dumps([ float(self.height_entry.text()), float(self.height_entry2.text()) ]) if units == "imperial" else str(float(self.height_entry.text())) if self.weight_loss_button.isChecked(): goal = "Weight loss" elif self.maintain_weight_button.isChecked(): goal = "Maintain weight" elif self.weight_gain_button.isChecked(): goal = "Weight gain" goal_params = json.dumps([ self.activity_level.currentText(), float(self.weight_per_week.currentText()) ]) if not goal == "Maintain weight" else json.dumps( ["Maintain", 0]) weight = str(float(self.weight_entry.text())) goal_weight = str(float(self.goal_weight_line_edit.text())) user_info = { "name": self.name_entry.text(), "age": age, "gender": gender, "units": units, "weight": weight, "height": height, "goal": goal, "goalparams": goal_params, "goalweight": goal_weight } except ValueError: return if not gender == "" and not units == "" and not self.name_entry.text( ) == "" and not self.weight_entry.text() == "": goal_params = json.loads(goal_params) self.db_wrapper.create_user(self.email, self.password) self.db_wrapper.create_user_table(self.email, self.password) self.db_wrapper.create_user_info_after_signup(user_info) calorie_goal_calculator = CalorieGoalCalculator( int(age), gender, float(height), float(weight), goal_params[0], goal, goal_params[1]) calorie_goal = calorie_goal_calculator.calculate_calorie_goal() self.db_wrapper.insert_default_values("Nutrition", calorie_goal=calorie_goal) self.db_wrapper.insert_default_values("Compound Exercises") self.db_wrapper.insert_default_values("Weight Loss") self.db_wrapper.insert_default_values("Workouts") self.display_layout_signal.emit("Compound Exercises")
class WorkoutPlanner(QWidget): def __init__(self): super().__init__() self.setStyleSheet(""" QWidget{ color:#c7c7c7; font-weight: bold; } QPushButton{ background-color: rgba(0, 0, 0, 0); border: 1px solid; font-size: 18px; font-weight: bold; border-color: #808080; min-height: 28px; white-space:nowrap; text-align: left; padding-left: 5%; font-family: Montserrat; } QPushButton:hover:!pressed{ border: 2px solid; border-color: #747474; } QPushButton:pressed{ border: 2px solid; background-color: #323232; border-color: #6C6C6C; }""") self.db_wrapper = DatabaseWrapper() self.table_name = "Workouts" self.db_wrapper.create_local_table(self.table_name) if self.db_wrapper.local_table_is_empty(self.table_name): self.db_wrapper.insert_default_values(self.table_name) self.fetched_workouts = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "workouts")) self.current_date = datetime.today().strftime("%d/%m/%Y") if not self.current_date in self.fetched_workouts: self.fetched_workouts[self.current_date] = { "Personal Notes": "", "Workout Name": "None" } self.db_wrapper.update_table_column( self.table_name, "workouts", json.dumps(self.fetched_workouts)) self.create_panel() def create_panel(self): self.grid = QGridLayout() self.grid.addWidget(self.create_calendar(), 0, 0, 2, 1) self.grid.addWidget(self.create_stats(), 0, 1, 2, 1) self.grid.addWidget(self.create_left_details(), 2, 0, 2, 1) self.grid.addWidget(self.create_right_details(), 2, 1, 2, 1) self.setLayout(self.grid) def create_calendar(self): frame = QFrame() frame.setFrameStyle(QFrame.StyledPanel) layout = QHBoxLayout() self.calendar = QCalendarWidget(self) self.calendar.setLocale(QLocale(QLocale.English)) self.calendar.setFirstDayOfWeek(Qt.DayOfWeek.Monday) self.calendar.clicked.connect(lambda: self.show_date()) layout.addWidget(self.calendar) frame.setLayout(layout) return frame def create_stats(self): frame = QFrame() frame.setFrameStyle(QFrame.StyledPanel) stats_layout = QVBoxLayout() stats_label = QLabel("Stats") stats_label.setFont(QFont("Ariel", 18, weight=QFont.Bold)) number_of_workouts = QLabel(" ".join([ "Total Number Of Workouts Done:", str(len(self.fetched_workouts)) ])) counter_this_month = 0 for date in self.fetched_workouts: if date.split("/")[1] == self.current_date.split("/")[1]: counter_this_month += 1 workouts_done_this_month = QLabel(" ".join( ["Workouts Done This Month:", str(counter_this_month)])) last_workout = list(self.fetched_workouts.keys())[-1] for date, workout in reversed(list(self.fetched_workouts.items())): if len(workout) > 1: # found workout that is not todays default last_workout = date break last_workout = QLabel(" ".join(["Last Workout:", last_workout])) stats_layout.addWidget(stats_label) stats_layout.addWidget(number_of_workouts) stats_layout.addWidget(workouts_done_this_month) stats_layout.addWidget(last_workout) frame.setLayout(stats_layout) return frame def create_left_details(self): frame = QFrame() frame.setFrameStyle(QFrame.StyledPanel) layout = QVBoxLayout() self.day_label = QLabel(self.current_date) self.day_label.setFont(QFont("Ariel", 18, weight=QFont.Bold)) workout_done_layout = QHBoxLayout() self.workout_done_label = QLabel(" ".join([ "Workout Done:", self.fetched_workouts[self.current_date]["Workout Name"] ])) workout_done_button = QPushButton("Change") workout_done_button.clicked.connect(lambda: self.change_workout_done()) workout_done_layout.addWidget(self.workout_done_label) workout_done_layout.addWidget(workout_done_button) specific_workout_layout = QHBoxLayout() specific_workout_label = QLabel( "Create a workout specific for one day: ") specific_workout_button = QPushButton("1 Time Workout") specific_workout_button.clicked.connect( lambda: self.show_1_time_window()) specific_workout_layout.addWidget(specific_workout_label) specific_workout_layout.addWidget(specific_workout_button) personal_notes_layout = QVBoxLayout() personal_notes_label = QLabel("Personal Notes:") self.text_edit = QTextEdit() self.text_edit.setStyleSheet("color: black;") self.text_edit.setText( self.fetched_workouts[self.current_date]["Personal Notes"]) self.personal_notes_save_button = QPushButton("Save Changes") self.personal_notes_save_button.clicked.connect( lambda: self.update_personal_notes()) personal_notes_layout.addWidget(personal_notes_label) personal_notes_layout.addWidget(self.text_edit) personal_notes_layout.addWidget(self.personal_notes_save_button) layout.addWidget(self.day_label) layout.addLayout(workout_done_layout) layout.addLayout(specific_workout_layout) layout.addLayout(personal_notes_layout) frame.setLayout(layout) return frame def create_right_details(self): frame = QFrame() frame.setFrameStyle(QFrame.StyledPanel) layout = QVBoxLayout() layout.setAlignment(Qt.AlignTop) details_label = QLabel("Workout Details") details_label.setFont(QFont("Ariel", 18, weight=QFont.Bold)) self.grid_layout = QGridLayout() name_label = QLabel("Exercise Name") sets_label = QLabel("Sets") reps_label = QLabel("Reps") rest_label = QLabel("Rest") layout.addWidget(details_label) self.grid_layout.addWidget(name_label, 0, 0) self.grid_layout.addWidget(sets_label, 0, 1) self.grid_layout.addWidget(reps_label, 0, 2) self.grid_layout.addWidget(rest_label, 0, 3) if "Exercises" in self.fetched_workouts[self.current_date]: exercises_count = len( self.fetched_workouts[self.current_date]["Exercises"]) self.number_of_exercises_label = QLabel(" ".join( ["Number of Exercises:", str(exercises_count)])) set_count = 0 for exercise in self.fetched_workouts[ self.current_date]["Exercises"]: set_count += int(self.fetched_workouts[self.current_date] ["Exercises"][exercise]["Sets"]) self.total_set_count_label = QLabel(" ".join( ["Total Set Count:", str(set_count)])) layout.addWidget(self.number_of_exercises_label) layout.addWidget(self.total_set_count_label) names_labels = [None] * len( self.fetched_workouts[self.current_date]["Exercises"].keys()) sets_labels = [None] * len( self.fetched_workouts[self.current_date]["Exercises"].keys()) reps_labels = [None] * len( self.fetched_workouts[self.current_date]["Exercises"].keys()) rest_labels = [None] * len( self.fetched_workouts[self.current_date]["Exercises"].keys()) j = 1 for i, exercise in enumerate(self.fetched_workouts[ self.current_date]["Exercises"].keys()): names_labels[i] = QLabel(exercise) sets_labels[i] = QLabel( str(self.fetched_workouts[self.current_date]["Exercises"] [exercise]["Sets"])) reps_labels[i] = QLabel( str(self.fetched_workouts[self.current_date]["Exercises"] [exercise]["Reps"])) rest_labels[i] = QLabel( str(self.fetched_workouts[self.current_date]["Exercises"] [exercise]["Rest"])) self.grid_layout.addWidget(names_labels[i], j, 0) self.grid_layout.addWidget(sets_labels[i], j, 1) self.grid_layout.addWidget(reps_labels[i], j, 2) self.grid_layout.addWidget(rest_labels[i], j, 3) j += 1 layout.addWidget(QLabel("")) layout.addLayout(self.grid_layout) frame.setLayout(layout) return frame def show_date(self): self.current_date = self.get_calendar_date() if not self.current_date in self.fetched_workouts: self.fetched_workouts[self.current_date] = { "Personal Notes": "", "Workout Name": "None" } self.day_label.setText(self.current_date) self.refresh_workout_done(True, True) self.text_edit.setText( self.fetched_workouts[self.current_date]["Personal Notes"]) def get_calendar_date(self): date = self.calendar.selectedDate() day = str(date.day()) if date.day() > 9 else "0" + str(date.day()) month = str( date.month()) if date.month() > 9 else "0" + str(date.month()) parsed_date = "/".join([day, month, str(date.year())]) return parsed_date def show_1_time_window(self): self.create_workout_window = CreateWorkoutWindow( one_time=True, date=self.get_calendar_date()) if self.db_wrapper.connection_exists: self.create_workout_window.refresh_after_creating_signal.connect( lambda signal: self.refresh_workout_done(signal)) self.create_workout_window.setGeometry(100, 200, 300, 300) self.create_workout_window.show() def update_personal_notes(self): self.fetched_workouts[self.current_date][ "Personal Notes"] = self.text_edit.toPlainText() self.db_wrapper.update_table_column(self.table_name, "workouts", json.dumps(self.fetched_workouts)) def change_workout_done(self): self.select_workout_window = SelectWorkout(self.get_calendar_date()) self.select_workout_window.refresh_workout_done_signal.connect( lambda signal: self.refresh_workout_done(signal)) self.select_workout_window.setGeometry(100, 200, 300, 300) self.select_workout_window.show() @pyqtSlot(bool) def refresh_workout_done(self, signal, date_change=False): if signal: if not date_change: self.fetched_workouts = json.loads( self.db_wrapper.fetch_local_column(self.table_name, "workouts")) self.workout_done_label.setText(" ".join([ "Workout Done:", self.fetched_workouts[self.current_date]["Workout Name"] ])) old_right_details_reference = self.grid.itemAt(3).widget() new_right_details = self.create_right_details() self.grid.replaceWidget(old_right_details_reference, new_right_details) old_right_details_reference.setParent(None)