generated from neutrons/python_project_template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Document GUI Standards. * update pics * update view and docs * move helper classes * remove required style if default value
- Loading branch information
1 parent
0a6218c
commit f4fc2c9
Showing
22 changed files
with
477 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
GUI Standards | ||
************** | ||
|
||
.. contents:: Table of Contents | ||
:local: | ||
:depth: 3 | ||
|
||
.. _gui_standards: | ||
|
||
|
||
Validation Strategy | ||
=================== | ||
|
||
GUI validation is a process aimed at ensuring the accuracy, functionality, and consistency of | ||
the graphical elements within a software application's user interface. It involves systematically | ||
examining and verifying that the graphical components, such as buttons, menus, and screens, behave | ||
as intended and meet specified design standards. Enforcing consistency is a key aspect, ensuring | ||
that the visual elements maintain a uniform appearance and behavior across different parts of | ||
the application, contributing to a cohesive and user-friendly interface. | ||
|
||
Effective GUI view validation is crucial for delivering a reliable and user-friendly software | ||
product, ensuring that the visual elements not only meet design specifications but also contribute | ||
to a positive and intuitive user experience. It is often an integral part of the software testing | ||
process, providing assurance that the graphical interface functions seamlessly and enhances the | ||
overall usability of the application. | ||
|
||
Helper functions streamline and standardize validation in software development. By encapsulating | ||
validation logic, they ensure consistency, reduce redundancy, and promote code reusability. These | ||
functions simplify maintenance, enhance code readability, and contribute to a modular and scalable | ||
code structure. We plan to create and implement these helper functions to optimize the validation | ||
process in our software development practices. | ||
|
||
Validation Items | ||
================ | ||
|
||
Fields | ||
###### | ||
|
||
In the user interface all fields will have tooltips with brief information about | ||
the usage of the fields in the workflows. Additionally, a placeholder text with an | ||
example value can be added in fields the describe complex ideas (e.g. x,y,z). The above | ||
will guide the users seamlessly through the data input process while ensuring clarity and | ||
adherence to form submission requirements. | ||
|
||
.. figure:: images/optional.png | ||
:align: center | ||
:alt: Optional Fields | ||
|
||
Optional Field with tooltip and placeholder text. | ||
|
||
|
||
Required Fields | ||
################ | ||
|
||
Required fields will be marked with an asterisk (*) at the end of the label. Required fields | ||
with no default values (text fields) will feature a light yellow background, serving as a widely | ||
adopted convention to visually cue users. This combination of visual indication, through both | ||
asterisks and background color enhances user experience. | ||
|
||
.. figure:: images/required.png | ||
:align: center | ||
:alt: Required Fields | ||
|
||
Required Field with asterisk and light yellow background. | ||
|
||
.. figure:: images/req-w-default.png | ||
:align: center | ||
:alt: Required Field with default value | ||
|
||
Required Field with default value and tooltip. | ||
|
||
|
||
Buttons | ||
####### | ||
|
||
In Qt applications, a best practice is to disable QPushButton, and similar objects, | ||
when associated required fields are empty or fail validation. This approach prevents | ||
users from attempting form submission with incomplete or incorrect data, promoting a | ||
more user-friendly experience by guiding them to address validation issues before proceeding. | ||
It ensures data integrity and contributes to a smoother interaction flow within the application. | ||
|
||
Buttons should also be given meaningful names, such as “Load Experiment Plan” rather than | ||
generic names like “Load”. If multiple buttons exist in the View, it should be clear to the | ||
use which input/output fields correspond to each button. This can be achieved through grouping | ||
fields and clear labels. | ||
|
||
.. figure:: images/button-disabled.png | ||
:align: center | ||
:alt: Button invalid | ||
|
||
Button with meaningful name and disabled state. | ||
|
||
.. figure:: images/button-enabled.png | ||
:align: center | ||
:alt: Button valid | ||
|
||
Button enabled after all fields are valid. | ||
|
||
Field Validation | ||
################ | ||
|
||
Implementing field validation with a red border for invalid entries is a visual cue | ||
that enhances user feedback in interfaces. This approach communicates validation errors | ||
immediately, aiding users in identifying and correcting input issues efficiently. The red | ||
border not only draws attention to the problematic fields but also ensures a clear and | ||
intuitive visual representation of where corrections are needed. Additionally, the status | ||
bar will dynamically change to provide hints on how to rectify the validation errors, | ||
contributing to a more user-friendly and error-tolerant design. The format of the message | ||
will follow this convention: | ||
|
||
<field_label1> : <error_message1> | ||
|
||
<field_label2> : <error_message2> | ||
|
||
Types of Validation | ||
------------------- | ||
|
||
Field Validation | ||
++++++++++++++++ | ||
|
||
Field validation, includes basic checks such as checks for minimum and maximum values or | ||
adherence to specific ranges, ensures data integrity in user input. This validation process | ||
runs as data is entered and enables buttons to become active only when the entered data meets | ||
predefined criteria. | ||
|
||
.. figure:: images/1invalid.png | ||
:align: center | ||
:alt: Field Validation | ||
|
||
Field validation with red border and status bar message for one invalid field. | ||
|
||
.. figure:: images/2invalid.png | ||
:align: center | ||
:alt: Field Validation | ||
|
||
Field validation with red border and status bar message for two invalid fields. | ||
|
||
|
||
Data Input Validation | ||
++++++++++++++++++++++++++ | ||
|
||
Data input validation occurs after enabling and pressing the button. | ||
This type of validation requires more complexity and can include things such as checking | ||
symmetry operations, valid file paths, and workspace existence. These inputs | ||
may include multiple criteria and require more than a cursory check to ensure they meet the | ||
underlying algorithm's requirements. If validation fails, the execution halts, prompting | ||
the user to update the failing values before proceeding. | ||
|
||
.. figure:: images/novalidation.png | ||
:align: center | ||
:alt: Data Input Validation | ||
|
||
Data input validation will occur after the button has been enabled and pressed. | ||
|
||
.. figure:: images/algo-fail-validation.png | ||
:align: center | ||
:alt: Data Input Validation | ||
|
||
If a field fails validation after the button has been invoked, a popup will appear to notify | ||
user and the field will be marked. | ||
|
||
.. figure:: images/red-until-after.png | ||
:align: center | ||
:alt: Data Input Validation | ||
|
||
After failing validation, button remains enabled and the fields that failed validation | ||
will be marked until the button is pressed again. | ||
|
||
.. figure:: images/all-valid.png | ||
:align: center | ||
:alt: Data Input Validation | ||
|
||
After pressing the button, the field will be revalidated and if valid, the field | ||
will be marked as valid and the algorith will run. | ||
|
||
Common Validation Items | ||
----------------------- | ||
|
||
Implementing common field validations, such as minimum and maximum values, is essential | ||
for data integrity. To streamline and reduce code redundancy, helper functions will be | ||
created that are dedicated to these types of validation. These functions not only promote | ||
consistency across the codebase but also enhance maintainability, making it easier to manage | ||
and update validation rules consistently throughout the software application. | ||
|
||
Error Handling | ||
############## | ||
|
||
Error handling involves utilizing both log messages and popups to enhance the debugging | ||
process and user experience. Log messages provide users and developers with detailed | ||
information about errors, warnings, and information for effective debugging. Popups | ||
offer users clear and concise error notifications when a process ends prematurely or | ||
with an error status, guiding users on how to proceed or address the issue. This dual | ||
approach ensures a comprehensive error management system, promoting smoother application | ||
functionality and facilitating efficient issue resolution. | ||
|
||
.. figure:: images/error-popup.png | ||
:align: center | ||
:alt: Error Handling | ||
|
||
Error handling with popup explaining the error. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,3 +45,4 @@ Contents | |
|
||
getting_started | ||
reference | ||
GUI_standards |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""__init__.py""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""__init__.py""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
"""BaseLineEdit | ||
------------ | ||
This module defines the BaseLineEdit class, a customized QLineEdit with setup and helper functions for | ||
QLineEdits used in Garnet. | ||
""" # noqa D205 | ||
|
||
from typing import Any, Optional | ||
|
||
from qtpy.QtWidgets import QLineEdit, QWidget | ||
|
||
INVALID_QLINEEDIT = """ | ||
QLineEdit { | ||
border-color: red; | ||
border-style: outset; | ||
border-width: 2px; | ||
border-radius: 4px; | ||
padding-left: -1px; | ||
padding-right: -1px; | ||
padding-top: 1px; | ||
padding-bottom: 1px; | ||
} | ||
""" | ||
|
||
REQUIRED_QLINEEDIT = """ | ||
QLineEdit { | ||
background-color: lightyellow; | ||
} | ||
""" | ||
|
||
|
||
class BaseLineEdit(QLineEdit): | ||
"""BaseLineEdit that inherits the QLineEdit. | ||
This class includes setup and helper functions for QLineEdits used in Garnet. | ||
:param required: Indicate whether the field is required. Defaults to False. | ||
:type required: bool, optional | ||
:param default_value: Set the default value for the field. Defaults to None. | ||
:type default_value: Any, optional | ||
:param parent: The parent object that holds the QLineEdit. Defaults to None. | ||
:type parent: Any, optional | ||
""" | ||
|
||
def __init__( | ||
self: Any, | ||
required: Optional[bool] = False, | ||
default_value: Optional[Any] = None, # noqa ANN401 | ||
parent: Optional[QWidget] = None, | ||
) -> None: | ||
"""Initialize the BaseLineEdit.""" | ||
super().__init__(parent) | ||
self.required = required | ||
self.default_value = default_value | ||
if default_value is not None: | ||
self.setText(str(default_value)) | ||
self.reset_style() | ||
|
||
def set_invalid_style(self: Any) -> None: | ||
"""Set field style as invalid | ||
If a validator determines the field is invalid, this function will be called | ||
and the field will be marked with a red border. | ||
""" | ||
self.setStyleSheet(INVALID_QLINEEDIT) | ||
|
||
def set_required_style(self: Any) -> None: | ||
"""If a field is required, the background will be set to light-yellow.""" | ||
self.setStyleSheet(REQUIRED_QLINEEDIT) | ||
|
||
def set_empty_style(self: Any) -> None: | ||
"""Once the field has been validated, the style will be cleared.""" | ||
self.setStyleSheet("") | ||
|
||
def reset_style(self: Any) -> None: | ||
"""Reset the style to its default.""" | ||
if self.required and self.default_value is None: | ||
self.set_required_style() | ||
else: | ||
self.set_empty_style() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
"""BaseStatusBar | ||
------------- | ||
This module defines the BaseStatusBar class, a custom status bar for PyQt applications. | ||
The BaseStatusBar provides functionality for displaying error messages and additional information | ||
through QLabel widgets. It includes methods to update the status label with error messages | ||
and the CWE (Caution, Warnings or Error) label with relevant information. | ||
""" # noqa D205 | ||
|
||
from typing import Any, Dict, Optional | ||
|
||
from qtpy.QtWidgets import QLabel, QStatusBar, QWidget | ||
|
||
|
||
class BaseStatusBar(QStatusBar): | ||
"""Custom status bar for displaying error messages and additional information.""" | ||
|
||
def __init__(self: Any, parent: Optional[QWidget] = None) -> None: | ||
"""Initialize the BaseStatusBar. | ||
:param parent: The parent widget. Defaults to None. | ||
:type parent: QWidget, optional | ||
""" | ||
super().__init__(parent) | ||
self.error_text: Dict[object, str] = {} | ||
self.setFixedWidth(600) | ||
self.cwe_label = QLabel("", self) | ||
self.status_label = QLabel("", self) | ||
self.addWidget(self.status_label) | ||
self.addPermanentWidget(self.cwe_label) | ||
|
||
def update_status_label(self: Any, error_text: Optional[Dict[object, str]] = None) -> bool: | ||
"""Update the status_label with the provided error_text. | ||
:param error_text: Dictionary of error messages. Defaults to None. | ||
:type error_text: Dict[object, str], optional | ||
:return bool: True if there are any invalid entries, False otherwise. | ||
""" | ||
if error_text is not None: | ||
for key in error_text: | ||
self.error_text[key] = error_text[key] | ||
|
||
self.error_text = {k: v for k, v in self.error_text.items() if v != ""} | ||
has_invalid = any(self.error_text.values()) | ||
self.status_label.setText("\n".join(self.error_text.values())) | ||
return has_invalid | ||
|
||
def update_cwe_label(self: Any, text: str) -> None: | ||
"""Update the cwe_label with the provided text. | ||
:param text: The text to be displayed in the Caution, Warning, Error label. | ||
:type text: str | ||
""" | ||
self.cwe_label.setText(text) |
Oops, something went wrong.