DEV Community

Cover image for FitVision - devlog #3
Eric Garcia
Eric Garcia

Posted on

FitVision - devlog #3

Hey everyone! πŸ‘‹
In this blog I will showcase the latest updates of my project.
Some of this important changes include:

  • Improvement of the User Interface
  • Light/dark mode
  • Settings window
  • Added a toolbar to the main page
  • Colored feedback

Also, I've made public the repo of the project in case anyone wants to take a detailed look at it: https://github.com/nairec/FitVision πŸ‘€

Let's jump right onto it!


Changes in the User Interface πŸ–₯️

Button display

The start and end detection buttons have been replaced by a toggle start/stop button and an end detection button.

class Home(QMainWindow): def __init__(self): ... self.pause_session_button.clicked.connect(self.update_pause_state) self.end_session_button.clicked.connect(self.end_detection) ... 
Enter fullscreen mode Exit fullscreen mode
class Home(QMainWindow): def initUI(self): self.paused = True self.detection_started = False ... self.end_session_button = QPushButton() self.end_session_button.setStyleSheet("width: 10px; height: 10px; margin-right: 200px") self.pause_session_button = QPushButton() self.pause_session_button.setStyleSheet("background: none; border: none; padding: 0px; margin-left: 200px") self.pause_session_button.setIcon(QIcon("icons/mediaplay.png")) self.pause_session_button.setIconSize(QSize(60, 60)) ... 
Enter fullscreen mode Exit fullscreen mode

The display of the info labels has also been changed, but the code is a 5-lines-for-each-label type of code, so I decided not to include it here.

The class Inherited by Home() has been changed from QWidget() to QMainWindow() to enable the new toolbar.

Some methods of the Home() class have been updated to work with the change in the display of the main buttons, and two new methods have been created: update_pause_state() and update_pause_icon()

class Home(QMainWidget): ... def start_detection(self): self.paused = False self.update_pause_icon() self.app_signals.start_detection.emit() ... 
Enter fullscreen mode Exit fullscreen mode
class Home(QMainWidget): ... def end_detection(self): self.paused = True self.detection_started = False self.update_pause_icon() self.app_signals.end_detection.emit() ... 
Enter fullscreen mode Exit fullscreen mode
class Home(QMainWidget): ... def update_pause_state(self): if self.detection_started: # If detection has already started, pause self.paused = not self.paused self.update_pause_icon() self.app_signals.pause_detection.emit(self.paused) else: # If detection hasn't started, start it self.detection_started = True self.start_detection() ... 
Enter fullscreen mode Exit fullscreen mode
class Home(QMainWidget): ... def update_pause_icon(self): if self.paused: self.pause_session_button.setIcon(QIcon("icons/mediaplay.png")) self.pause_session_button.setIconSize(QSize(60, 60)) else: self.pause_session_button.setIcon(QIcon("icons/mediapause.png")) self.pause_session_button.setIconSize(QSize(60, 60)) ... 
Enter fullscreen mode Exit fullscreen mode

Colored feedback

Now, the user has the option to enable or disable (it is enabled by default) a coloration in the labels that show the information like rep count, timer, etc.
This coloration is based on the average values that would be considered low/medium/high or excessive/addequate.

class Home(QMainWindow): def __init__(self): ... self.feedback_on = True self.bad_feedback_color = "#94322E" self.medium_feedback_color = "#F0E68C" self.good_feedback_color = "#80FF80" ... 
Enter fullscreen mode Exit fullscreen mode

The logic behind the actual coloration of the labels is formed of some if statements that check the intervals of the values.

Color themes

Obviously, an application is not properly designed if it doesn't have an option to change between light and dark modes, so I added that posibility in the settings window.

The changes on the UI style based on the color theme selected are defined in a new method called toggle_theme().
I will skip the explanation of this method because it's mainly just boring CSS, and nobody likes CSS around here πŸ₯±.

Settings window βš™οΈ

For communicating changes in the settings I created a new signal class

class SettingsSignals(QObject): toggle_feedback = pyqtSignal(bool) toggle_theme = pyqtSignal(str) 
Enter fullscreen mode Exit fullscreen mode

The first signal sends a bool value that represents wether the colored feedback is on or off, and the second one sends the selected color theme.

The class for the settings window is formed by inheriting the QWidget class and takes as parameters the SettingsSignals object and the current value of the color theme for defining the pre-selected theme on the combobox when opening the window.

class SettingsWindow(QWidget): def __init__(self, settings_signals:SettingsSignals, currentTheme:str): ... 
Enter fullscreen mode Exit fullscreen mode

I won't show fully the code of this class as it is not that interesting, but the two methods that control the change in feedback and theme options are the following:

class SettingsWindow(QWidget): ... def apply_toggle_feedback(self, state:bool): if state == Qt.Checked: self.settings_signals.toggle_feedback.emit(True) else: self.settings_signals.toggle_feedback.emit(False) def apply_toggle_theme(self, theme:str): self.settings_signals.toggle_theme.emit(theme) 
Enter fullscreen mode Exit fullscreen mode

The first one emits the value of the checkbox and the second one emits the label of the selected color theme.

Results! βœ…

Light mode, colored feedback disabled:

Image visualization of the two windows on light mode, colored feedback disabled

Light mode, colored feedback enabled:

Image visualization of the two windows on light mode, colored feedback enabled

Dark mode, colored feedback disabled:

Image visualization of the two windows on darkmode, colored feedback disabled

Dark mode, colored feedback enabled:

Image visualization of the two windows on dark mode, colored feedback enabled

Next steps πŸ“‘

  • Saving session records
  • New color themes ?
  • Personalized color feedback

Thank you for reaching the end of the blog and see you in the next!

Top comments (0)