diff --git a/.gitignore b/.gitignore index b6e4761..3ad5395 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,6 @@ dmypy.json # Pyre type checker .pyre/ + +.DS_Store +target/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..32337aa --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +# Physical Units Converter +5 minute test project by lapisangularis + +## Installation +#### Requirements +Application works fine on the newest Windows, MacOSX and linux distributions. + +#### Installation & Running +Double click on the executable. + +## Usage +Write your value in the first field. Pick your conversion method from available buttons. Click the reset button for the default value and conversion (1kg to lb). Converted value will appear in the second field. +## Development + +#### Requirements + + - `python 3.7.3` + - `pip 20.1.1` + +#### Setting up project + +If you meet the `Requirements`, you can develop this codebase, just need to setup the environment. + +Instructions to do in commandline or terminal: + + 1. Go to main folder of the project + - Windows `cd c:\path\to\project` + - MacOSX and Linux `cd /path/to/project` + 2. Create new virtualenv + - `python3 -m venv venv` + 3. Activate virtualenv + - Windows `call venv/scripts/activate.bat` + - MacOSX and Linux `source venv/bin/activate` + 4. Install packages with `pip` + - `pip install -r requirements.txt ` + +For running the app, type: + - `fbs run` + +#### Executable, compilation + +For creating executable, after `Setting up project` part, you just need to type. + + - `fbs freeze` + +In project folder there will be `target` folder with executable inside. (`.exe` for Windows, `.app` for MacOSX, binary for Linux) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c99068e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,68 @@ +altgraph==0.17 +appnope==0.1.0 +attrs==19.3.0 +backcall==0.1.0 +bleach==3.1.5 +cycler==0.10.0 +decorator==4.4.2 +defusedxml==0.6.0 +entrypoints==0.3 +fbs==0.8.6 +future==0.18.2 +importlib-metadata==1.6.0 +ipykernel==5.3.0 +ipython==7.14.0 +ipython-genutils==0.2.0 +ipywidgets==7.5.1 +jedi==0.17.0 +Jinja2==2.11.2 +jsonschema==3.2.0 +jupyter==1.0.0 +jupyter-client==6.1.3 +jupyter-console==6.1.0 +jupyter-core==4.6.3 +kiwisolver==1.2.0 +macholib==1.14 +MarkupSafe==1.1.1 +matplotlib==3.2.1 +mistune==0.8.4 +mpmath==1.1.0 +nbconvert==5.6.1 +nbformat==5.0.6 +nose==1.3.7 +notebook==6.0.3 +numpy==1.18.4 +packaging==20.4 +pandas==1.0.4 +pandocfilters==1.4.2 +parso==0.7.0 +pefile==2019.4.18 +pexpect==4.8.0 +pickleshare==0.7.5 +prometheus-client==0.8.0 +prompt-toolkit==3.0.5 +ptyprocess==0.6.0 +Pygments==2.6.1 +PyInstaller==3.4 +pyparsing==2.4.7 +PyQt5==5.9.2 +PyQt5-stubs==5.14.2.2 +pyrsistent==0.16.0 +python-dateutil==2.8.1 +pytz==2020.1 +pyzmq==19.0.1 +qtconsole==4.7.4 +QtPy==1.9.0 +scipy==1.4.1 +Send2Trash==1.5.0 +sip==4.19.8 +six==1.15.0 +sympy==1.6 +terminado==0.8.3 +testpath==0.4.4 +tornado==6.0.4 +traitlets==4.3.3 +wcwidth==0.1.9 +webencodings==0.5.1 +widgetsnbextension==3.5.1 +zipp==3.1.0 diff --git a/src/build/settings/base.json b/src/build/settings/base.json new file mode 100644 index 0000000..efa89c3 --- /dev/null +++ b/src/build/settings/base.json @@ -0,0 +1,6 @@ +{ + "app_name": "physical-units-converter", + "author": "lapisangularis", + "main_module": "src/main/python/__main__.py", + "version": "1.0.0" +} \ No newline at end of file diff --git a/src/build/settings/linux.json b/src/build/settings/linux.json new file mode 100644 index 0000000..8524d42 --- /dev/null +++ b/src/build/settings/linux.json @@ -0,0 +1,6 @@ +{ + "categories": "Utility;", + "description": "Physical Units Converter", + "author_email": "lapis@angularis.pl", + "url": "" +} \ No newline at end of file diff --git a/src/build/settings/mac.json b/src/build/settings/mac.json new file mode 100644 index 0000000..2e268e5 --- /dev/null +++ b/src/build/settings/mac.json @@ -0,0 +1,3 @@ +{ + "mac_bundle_identifier": "com.lapisangularis.physical-units-converter" +} \ No newline at end of file diff --git a/src/main/icons/Icon.ico b/src/main/icons/Icon.ico new file mode 100644 index 0000000..3312d86 Binary files /dev/null and b/src/main/icons/Icon.ico differ diff --git a/src/main/icons/base/16.png b/src/main/icons/base/16.png new file mode 100755 index 0000000..f7d02dc Binary files /dev/null and b/src/main/icons/base/16.png differ diff --git a/src/main/icons/base/24.png b/src/main/icons/base/24.png new file mode 100755 index 0000000..faa6710 Binary files /dev/null and b/src/main/icons/base/24.png differ diff --git a/src/main/icons/base/32.png b/src/main/icons/base/32.png new file mode 100755 index 0000000..36b25e8 Binary files /dev/null and b/src/main/icons/base/32.png differ diff --git a/src/main/icons/base/48.png b/src/main/icons/base/48.png new file mode 100755 index 0000000..4a5dcbd Binary files /dev/null and b/src/main/icons/base/48.png differ diff --git a/src/main/icons/base/64.png b/src/main/icons/base/64.png new file mode 100755 index 0000000..4b0a423 Binary files /dev/null and b/src/main/icons/base/64.png differ diff --git a/src/main/icons/linux/1024.png b/src/main/icons/linux/1024.png new file mode 100755 index 0000000..2248377 Binary files /dev/null and b/src/main/icons/linux/1024.png differ diff --git a/src/main/icons/linux/128.png b/src/main/icons/linux/128.png new file mode 100755 index 0000000..05b2b35 Binary files /dev/null and b/src/main/icons/linux/128.png differ diff --git a/src/main/icons/linux/256.png b/src/main/icons/linux/256.png new file mode 100755 index 0000000..578fdc7 Binary files /dev/null and b/src/main/icons/linux/256.png differ diff --git a/src/main/icons/linux/512.png b/src/main/icons/linux/512.png new file mode 100755 index 0000000..0fbac4f Binary files /dev/null and b/src/main/icons/linux/512.png differ diff --git a/src/main/icons/mac/1024.png b/src/main/icons/mac/1024.png new file mode 100644 index 0000000..c1c8691 Binary files /dev/null and b/src/main/icons/mac/1024.png differ diff --git a/src/main/icons/mac/128.png b/src/main/icons/mac/128.png new file mode 100644 index 0000000..de9bee6 Binary files /dev/null and b/src/main/icons/mac/128.png differ diff --git a/src/main/icons/mac/256.png b/src/main/icons/mac/256.png new file mode 100644 index 0000000..c3a68b9 Binary files /dev/null and b/src/main/icons/mac/256.png differ diff --git a/src/main/icons/mac/512.png b/src/main/icons/mac/512.png new file mode 100644 index 0000000..b2fc07e Binary files /dev/null and b/src/main/icons/mac/512.png differ diff --git a/src/main/python/__main__.py b/src/main/python/__main__.py new file mode 100644 index 0000000..8945661 --- /dev/null +++ b/src/main/python/__main__.py @@ -0,0 +1,26 @@ +import sys +from fbs_runtime.application_context.PyQt5 import ApplicationContext +from models.conversion import Conversion +from views.converter_view import ConverterView +from controllers.converter_controller import ConverterController + + +class AppContext(ApplicationContext): + def _setup_converter(self): + self.conversion_model = Conversion() + self.converter_controller = ConverterController(self.conversion_model) + self.converter_view = ConverterView(self.conversion_model, self.converter_controller) + + def __init__(self): + super(AppContext, self).__init__() + self._setup_converter() + + def run(self): + self.converter_view.show() + return self.app.exec_() + + +if __name__ == '__main__': + app_context = AppContext() + exit_code = app_context.run() + sys.exit(exit_code) diff --git a/src/main/python/controllers/converter_controller.py b/src/main/python/controllers/converter_controller.py new file mode 100644 index 0000000..28b8634 --- /dev/null +++ b/src/main/python/controllers/converter_controller.py @@ -0,0 +1,130 @@ +from PyQt5.QtCore import QObject, pyqtSlot + + +class ConverterController(QObject): + def __init__(self, model): + super().__init__() + self._model = model + + def _calculate_reset_state(self, value): + self._model.enable_reset = True if value else False + + @pyqtSlot(int) + def calculate_kilograms_to_pounds(self, value): + self._model.input_value = float(value) + self._model.kilograms_to_pounds() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_pounds_to_kilograms(self, value): + self._model.input_value = float(value) + self._model.pounds_to_kilograms() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_grams_to_pounds(self, value): + self._model.input_value = float(value) + self._model.grams_to_pounds() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_pounds_to_grams(self, value): + self._model.input_value = float(value) + self._model.pounds_to_grams() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_kilograms_to_ounces(self, value): + self._model.input_value = float(value) + self._model.kilograms_to_ounces() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_ounces_to_kilograms(self, value): + self._model.input_value = float(value) + self._model.ounces_to_kilograms() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_grams_to_ounces(self, value): + self._model.input_value = float(value) + self._model.grams_to_ounces() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_ounces_to_grams(self, value): + self._model.input_value = float(value) + self._model.ounces_to_grams() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_meters_to_inches(self, value): + self._model.input_value = float(value) + self._model.meters_to_inches() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_inches_to_meters(self, value): + self._model.input_value = float(value) + self._model.inches_to_meters() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_meters_to_feet(self, value): + self._model.input_value = float(value) + self._model.meters_to_feet() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_feet_to_meters(self, value): + self._model.input_value = float(value) + self._model.feet_to_meters() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_meters_to_yards(self, value): + self._model.input_value = float(value) + self._model.meters_to_yards() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_yards_to_meters(self, value): + self._model.input_value = float(value) + self._model.yards_to_meters() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_meters_to_miles(self, value): + self._model.input_value = float(value) + self._model.meters_to_miles() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_miles_to_meters(self, value): + self._model.input_value = float(value) + self._model.miles_to_meters() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_joules_to_ev(self, value): + self._model.input_value = float(value) + self._model.joules_to_ev() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_ev_to_joules(self, value): + self._model.input_value = float(value) + self._model.ev_to_joules() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_joules_to_calories(self, value): + self._model.input_value = float(value) + self._model.joules_to_calories() + self._calculate_reset_state(value) + + @pyqtSlot(int) + def calculate_calories_to_joules(self, value): + self._model.input_value = float(value) + self._model.calories_to_joules() + self._calculate_reset_state(value) diff --git a/src/main/python/models/conversion.py b/src/main/python/models/conversion.py new file mode 100644 index 0000000..d8f97c1 --- /dev/null +++ b/src/main/python/models/conversion.py @@ -0,0 +1,101 @@ +from PyQt5.QtCore import QObject, pyqtSignal +from scipy import constants + + +class Conversion(QObject): + input_value_changed = pyqtSignal(float) + output_value_changed = pyqtSignal(float) + enable_reset_changed = pyqtSignal(bool) + + def __init__(self): + super().__init__() + self._input_value = 0 + self._output_value = 0 + self._enable_reset = False + + @property + def input_value(self): + return self._input_value + + @input_value.setter + def input_value(self, value): + self._input_value = value + self.input_value_changed.emit(value) + + @property + def output_value(self): + return self._output_value + + @output_value.setter + def output_value(self, value): + self._output_value = value + self.output_value_changed.emit(value) + + @property + def enable_reset(self): + return self._enable_reset + + @enable_reset.setter + def enable_reset(self, value): + self._enable_reset = value + self.enable_reset_changed.emit(value) + + def kilograms_to_pounds(self): + self.output_value = (1 / constants.pound) * self.input_value + + def pounds_to_kilograms(self): + self.output_value = constants.pound * self.input_value + + def grams_to_pounds(self): + self.output_value = (1 / constants.pound) * self.input_value * constants.gram + + def pounds_to_grams(self): + self.output_value = constants.pound * self.input_value * constants.gram + + def kilograms_to_ounces(self): + self.output_value = (1 / constants.ounce) * self.input_value + + def ounces_to_kilograms(self): + self.output_value = constants.ounce * self.input_value + + def grams_to_ounces(self): + self.output_value = (1 / constants.ounce) * self.input_value * constants.gram + + def ounces_to_grams(self): + self.output_value = constants.ounce * self.input_value * constants.gram + + def meters_to_inches(self): + self.output_value = (1 / constants.inch) * self.input_value + + def inches_to_meters(self): + self.output_value = constants.inch * self.input_value + + def meters_to_feet(self): + self.output_value = (1 / constants.foot) * self.input_value + + def feet_to_meters(self): + self.output_value = constants.foot * self.input_value + + def meters_to_yards(self): + self.output_value = (1 / constants.yard) * self.input_value + + def yards_to_meters(self): + self.output_value = constants.yard * self.input_value + + def meters_to_miles(self): + self.output_value = (1 / constants.mile) * self.input_value + + def miles_to_meters(self): + self.output_value = constants.mile * self.input_value + + def joules_to_ev(self): + self.output_value = (1 / constants.eV) * self.input_value + + def ev_to_joules(self): + self.output_value = constants.eV * self.input_value + + def joules_to_calories(self): + self.output_value = (1 / constants.calorie) * self.input_value + + def calories_to_joules(self): + self.output_value = constants.calorie * self.input_value diff --git a/src/main/python/views/converter_ui.py b/src/main/python/views/converter_ui.py new file mode 100644 index 0000000..4681e9d --- /dev/null +++ b/src/main/python/views/converter_ui.py @@ -0,0 +1,210 @@ +from PyQt5 import QtCore, QtGui, QtWidgets + + +class ConverterUi(object): + def _setup_layouts(self): + self.vbox_layout = QtWidgets.QVBoxLayout(self.central_widget) + self.vbox_layout.setObjectName("vboxlayout") + self.vertical_layout = QtWidgets.QVBoxLayout() + self.vertical_layout.setObjectName("vertical_layout") + self.horizontal_layout = QtWidgets.QHBoxLayout() + self.horizontal_layout.setObjectName("horizontal_layout") + self.horizontal_layout_2 = QtWidgets.QHBoxLayout() + self.horizontal_layout_2.setObjectName("horizontal_layout_2") + self.horizontal_layout_3 = QtWidgets.QHBoxLayout() + self.horizontal_layout_3.setObjectName("horizontal_layout_3") + self.horizontal_layout_4 = QtWidgets.QHBoxLayout() + self.horizontal_layout_4.setObjectName("horizontal_layout_4") + self.horizontal_layout_5 = QtWidgets.QHBoxLayout() + self.horizontal_layout_5.setObjectName("horizontal_layout_5") + self.horizontal_layout_6 = QtWidgets.QHBoxLayout() + self.horizontal_layout_6.setObjectName("horizontal_layout_6") + + def _setup_edit_fields(self): + self.line_edit_input_value = QtWidgets.QLineEdit(self.central_widget) + self.line_edit_input_value.setObjectName("line_edit_input_value") + self.line_edit_input_value.setValidator(QtGui.QDoubleValidator(decimals=10)) + self.line_edit_output_value = QtWidgets.QLineEdit(self.central_widget) + self.line_edit_output_value.setObjectName("line_edit_output_value") + + self.push_button_reset = QtWidgets.QPushButton(self.central_widget) + self.push_button_reset.setEnabled(False) + self.push_button_reset.setObjectName("push_button_reset") + + self.horizontal_layout.addWidget(self.line_edit_input_value) + self.horizontal_layout.addWidget(self.line_edit_output_value) + self.horizontal_layout.addWidget(self.push_button_reset) + + def _setup_pounds(self): + self.push_button_kilograms_to_pounds = QtWidgets.QPushButton(self.central_widget) + self.push_button_kilograms_to_pounds.setEnabled(True) + self.push_button_kilograms_to_pounds.setObjectName("push_button_kilograms_to_pounds") + self.horizontal_layout_2.addWidget(self.push_button_kilograms_to_pounds) + + self.push_button_pounds_to_kilograms = QtWidgets.QPushButton(self.central_widget) + self.push_button_pounds_to_kilograms.setEnabled(True) + self.push_button_pounds_to_kilograms.setObjectName("push_button_pounds_to_kilograms") + self.horizontal_layout_2.addWidget(self.push_button_pounds_to_kilograms) + + self.push_button_grams_to_pounds = QtWidgets.QPushButton(self.central_widget) + self.push_button_grams_to_pounds.setEnabled(True) + self.push_button_grams_to_pounds.setObjectName("push_button_grams_to_pounds") + self.horizontal_layout_2.addWidget(self.push_button_grams_to_pounds) + + self.push_button_pounds_to_grams = QtWidgets.QPushButton(self.central_widget) + self.push_button_pounds_to_grams.setEnabled(True) + self.push_button_pounds_to_grams.setObjectName("push_button_pounds_to_grams") + self.horizontal_layout_2.addWidget(self.push_button_pounds_to_grams) + + def _setup_ounces(self): + self.push_button_kilograms_to_ounces = QtWidgets.QPushButton(self.central_widget) + self.push_button_kilograms_to_ounces.setEnabled(True) + self.push_button_kilograms_to_ounces.setObjectName("push_button_kilograms_to_ounces") + self.horizontal_layout_3.addWidget(self.push_button_kilograms_to_ounces) + + self.push_button_ounces_to_kilograms = QtWidgets.QPushButton(self.central_widget) + self.push_button_ounces_to_kilograms.setEnabled(True) + self.push_button_ounces_to_kilograms.setObjectName("push_button_ounces_to_kilograms") + self.horizontal_layout_3.addWidget(self.push_button_ounces_to_kilograms) + + self.push_button_grams_to_ounces = QtWidgets.QPushButton(self.central_widget) + self.push_button_grams_to_ounces.setEnabled(True) + self.push_button_grams_to_ounces.setObjectName("push_button_grams_to_ounces") + self.horizontal_layout_3.addWidget(self.push_button_grams_to_ounces) + + self.push_button_ounces_to_grams = QtWidgets.QPushButton(self.central_widget) + self.push_button_ounces_to_grams.setEnabled(True) + self.push_button_ounces_to_grams.setObjectName("push_button_ounces_to_grams") + self.horizontal_layout_3.addWidget(self.push_button_ounces_to_grams) + + def _setup_inches(self): + self.push_button_meters_to_inches = QtWidgets.QPushButton(self.central_widget) + self.push_button_meters_to_inches.setEnabled(True) + self.push_button_meters_to_inches.setObjectName("push_button_meters_to_inches") + self.horizontal_layout_4.addWidget(self.push_button_meters_to_inches) + + self.push_button_inches_to_meters = QtWidgets.QPushButton(self.central_widget) + self.push_button_inches_to_meters.setEnabled(True) + self.push_button_inches_to_meters.setObjectName("push_button_inches_to_meters") + self.horizontal_layout_4.addWidget(self.push_button_inches_to_meters) + + def _setup_feet(self): + self.push_button_meters_to_feet = QtWidgets.QPushButton(self.central_widget) + self.push_button_meters_to_feet.setEnabled(True) + self.push_button_meters_to_feet.setObjectName("push_button_meters_to_feet") + self.horizontal_layout_4.addWidget(self.push_button_meters_to_feet) + + self.push_button_feet_to_meters = QtWidgets.QPushButton(self.central_widget) + self.push_button_feet_to_meters.setEnabled(True) + self.push_button_feet_to_meters.setObjectName("push_button_feet_to_meters") + self.horizontal_layout_4.addWidget(self.push_button_feet_to_meters) + + def _setup_yards(self): + self.push_button_meters_to_yards = QtWidgets.QPushButton(self.central_widget) + self.push_button_meters_to_yards.setEnabled(True) + self.push_button_meters_to_yards.setObjectName("push_button_meters_to_yards") + self.horizontal_layout_5.addWidget(self.push_button_meters_to_yards) + + self.push_button_yards_to_meters = QtWidgets.QPushButton(self.central_widget) + self.push_button_yards_to_meters.setEnabled(True) + self.push_button_yards_to_meters.setObjectName("push_button_yards_to_meters") + self.horizontal_layout_5.addWidget(self.push_button_yards_to_meters) + + def _setup_miles(self): + self.push_button_meters_to_miles = QtWidgets.QPushButton(self.central_widget) + self.push_button_meters_to_miles.setEnabled(True) + self.push_button_meters_to_miles.setObjectName("push_button_meters_to_miles") + self.horizontal_layout_5.addWidget(self.push_button_meters_to_miles) + + self.push_button_miles_to_meters = QtWidgets.QPushButton(self.central_widget) + self.push_button_miles_to_meters.setEnabled(True) + self.push_button_miles_to_meters.setObjectName("push_button_miles_to_meters") + self.horizontal_layout_5.addWidget(self.push_button_miles_to_meters) + + def _setup_ev(self): + self.push_button_joules_to_ev = QtWidgets.QPushButton(self.central_widget) + self.push_button_joules_to_ev.setEnabled(True) + self.push_button_joules_to_ev.setObjectName("push_button_joules_to_ev") + self.horizontal_layout_6.addWidget(self.push_button_joules_to_ev) + + self.push_button_ev_to_joules = QtWidgets.QPushButton(self.central_widget) + self.push_button_ev_to_joules.setEnabled(True) + self.push_button_ev_to_joules.setObjectName("push_button_ev_to_joules") + self.horizontal_layout_6.addWidget(self.push_button_ev_to_joules) + + def _setup_calories(self): + self.push_button_joules_to_calories = QtWidgets.QPushButton(self.central_widget) + self.push_button_joules_to_calories.setEnabled(True) + self.push_button_joules_to_calories.setObjectName("push_button_joules_to_calories") + self.horizontal_layout_6.addWidget(self.push_button_joules_to_calories) + + self.push_button_calories_to_joules = QtWidgets.QPushButton(self.central_widget) + self.push_button_calories_to_joules.setEnabled(True) + self.push_button_calories_to_joules.setObjectName("push_button_calories_to_joules") + self.horizontal_layout_6.addWidget(self.push_button_calories_to_joules) + + def setup_ui(self, main_window): + main_window.setObjectName("main_window") + main_window.resize(500, 50) + self.central_widget = QtWidgets.QWidget(main_window) + self.central_widget.setObjectName("central_widget") + self._setup_layouts() + + spacer_item = QtWidgets.QSpacerItem(10, 5, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.vertical_layout.addItem(spacer_item) + + self._setup_edit_fields() + self._setup_pounds() + self._setup_ounces() + self._setup_inches() + self._setup_feet() + self._setup_yards() + self._setup_miles() + self._setup_ev() + self._setup_calories() + + self.vertical_layout.addLayout(self.horizontal_layout) + self.vertical_layout.addLayout(self.horizontal_layout_2) + self.vertical_layout.addLayout(self.horizontal_layout_3) + self.vertical_layout.addLayout(self.horizontal_layout_4) + self.vertical_layout.addLayout(self.horizontal_layout_5) + self.vertical_layout.addLayout(self.horizontal_layout_6) + + self.vbox_layout.addLayout(self.vertical_layout) + main_window.setCentralWidget(self.central_widget) + + self.translate_ui(main_window) + QtCore.QMetaObject.connectSlotsByName(main_window) + + def translate_ui(self, main_window): + _translate = QtCore.QCoreApplication.translate + self.central_widget.setWindowTitle(_translate("main_window", "Physical Units Converter")) + self.push_button_reset.setText(_translate("main_window", "Reset")) + + self.push_button_kilograms_to_pounds.setText(_translate("main_window", "kg / lb")) + self.push_button_pounds_to_kilograms.setText(_translate("main_window", "lb / kg")) + self.push_button_grams_to_pounds.setText(_translate("main_window", "g / lb")) + self.push_button_pounds_to_grams.setText(_translate("main_window", "lb / g")) + + self.push_button_kilograms_to_ounces.setText(_translate("main_window", "kg / oz")) + self.push_button_ounces_to_kilograms.setText(_translate("main_window", "oz / kg")) + self.push_button_grams_to_ounces.setText(_translate("main_window", "g / oz")) + self.push_button_ounces_to_grams.setText(_translate("main_window", "oz / g")) + + self.push_button_meters_to_inches.setText(_translate("main_window", "m / in")) + self.push_button_inches_to_meters.setText(_translate("main_window", "in / m")) + + self.push_button_meters_to_feet.setText(_translate("main_window", "m / ft")) + self.push_button_feet_to_meters.setText(_translate("main_window", "ft / m")) + + self.push_button_meters_to_yards.setText(_translate("main_window", "m / yd")) + self.push_button_yards_to_meters.setText(_translate("main_window", "yd / m")) + + self.push_button_meters_to_miles.setText(_translate("main_window", "m / mi")) + self.push_button_miles_to_meters.setText(_translate("main_window", "mi / m")) + + self.push_button_joules_to_ev.setText(_translate("main_window", "J / eV")) + self.push_button_ev_to_joules.setText(_translate("main_window", "eV / J")) + + self.push_button_joules_to_calories.setText(_translate("main_window", "J / cal")) + self.push_button_calories_to_joules.setText(_translate("main_window", "cal / J")) diff --git a/src/main/python/views/converter_view.py b/src/main/python/views/converter_view.py new file mode 100644 index 0000000..f2cffc4 --- /dev/null +++ b/src/main/python/views/converter_view.py @@ -0,0 +1,102 @@ +from PyQt5.QtWidgets import QMainWindow +from PyQt5.QtCore import pyqtSlot +from .converter_ui import ConverterUi + + +class ConverterView(QMainWindow): + def _connect_actions_pounds(self): + self._ui.push_button_kilograms_to_pounds.clicked.connect( + lambda: self._controller.calculate_kilograms_to_pounds(self._ui.line_edit_input_value.text())) + self._ui.push_button_pounds_to_kilograms.clicked.connect( + lambda: self._controller.calculate_pounds_to_kilograms(self._ui.line_edit_input_value.text())) + self._ui.push_button_grams_to_pounds.clicked.connect( + lambda: self._controller.calculate_grams_to_pounds(self._ui.line_edit_input_value.text())) + self._ui.push_button_pounds_to_grams.clicked.connect( + lambda: self._controller.calculate_pounds_to_grams(self._ui.line_edit_input_value.text())) + + def _connect_actions_ounces(self): + self._ui.push_button_kilograms_to_ounces.clicked.connect( + lambda: self._controller.calculate_kilograms_to_ounces(self._ui.line_edit_input_value.text())) + self._ui.push_button_ounces_to_kilograms.clicked.connect( + lambda: self._controller.calculate_ounces_to_kilograms(self._ui.line_edit_input_value.text())) + self._ui.push_button_grams_to_ounces.clicked.connect( + lambda: self._controller.calculate_grams_to_ounces(self._ui.line_edit_input_value.text())) + self._ui.push_button_ounces_to_grams.clicked.connect( + lambda: self._controller.calculate_ounces_to_grams(self._ui.line_edit_input_value.text())) + + def _connect_actions_inches(self): + self._ui.push_button_meters_to_inches.clicked.connect( + lambda: self._controller.calculate_meters_to_inches(self._ui.line_edit_input_value.text())) + self._ui.push_button_inches_to_meters.clicked.connect( + lambda: self._controller.calculate_inches_to_meters(self._ui.line_edit_input_value.text())) + + def _connect_actions_feet(self): + self._ui.push_button_meters_to_feet.clicked.connect( + lambda: self._controller.calculate_meters_to_feet(self._ui.line_edit_input_value.text())) + self._ui.push_button_feet_to_meters.clicked.connect( + lambda: self._controller.calculate_feet_to_meters(self._ui.line_edit_input_value.text())) + + def _connect_actions_yards(self): + self._ui.push_button_meters_to_yards.clicked.connect( + lambda: self._controller.calculate_meters_to_yards(self._ui.line_edit_input_value.text())) + self._ui.push_button_yards_to_meters.clicked.connect( + lambda: self._controller.calculate_yards_to_meters(self._ui.line_edit_input_value.text())) + + def _connect_actions_miles(self): + self._ui.push_button_meters_to_miles.clicked.connect( + lambda: self._controller.calculate_meters_to_miles(self._ui.line_edit_input_value.text())) + self._ui.push_button_miles_to_meters.clicked.connect( + lambda: self._controller.calculate_miles_to_meters(self._ui.line_edit_input_value.text())) + + def _connect_actions_ev(self): + self._ui.push_button_joules_to_ev.clicked.connect( + lambda: self._controller.calculate_joules_to_ev(self._ui.line_edit_input_value.text())) + self._ui.push_button_ev_to_joules.clicked.connect( + lambda: self._controller.calculate_ev_to_joules(self._ui.line_edit_input_value.text())) + + def _connect_actions_calories(self): + self._ui.push_button_joules_to_calories.clicked.connect( + lambda: self._controller.calculate_joules_to_calories(self._ui.line_edit_input_value.text())) + self._ui.push_button_calories_to_joules.clicked.connect( + lambda: self._controller.calculate_calories_to_joules(self._ui.line_edit_input_value.text())) + + def _connect_actions(self): + self._connect_actions_pounds() + self._connect_actions_ounces() + self._connect_actions_inches() + self._connect_actions_feet() + self._connect_actions_yards() + self._connect_actions_miles() + self._connect_actions_ev() + self._connect_actions_calories() + self._ui.push_button_reset.clicked.connect(lambda: self._controller.calculate_kilograms_to_pounds(1)) + + def _update_ui(self): + self._model.input_value_changed.connect(self.on_input_value_changed) + self._model.output_value_changed.connect(self.on_output_value_changed) + self._model.enable_reset_changed.connect(self.on_enable_reset_changed) + + def _set_defaults(self): + self._controller.calculate_kilograms_to_pounds(1) + + def __init__(self, model, controller): + super().__init__() + self._model = model + self._controller = controller + self._ui = ConverterUi() + self._ui.setup_ui(self) + self._connect_actions() + self._update_ui() + self._set_defaults() + + @pyqtSlot(float) + def on_input_value_changed(self, value): + self._ui.line_edit_input_value.setText(str(value)) + + @pyqtSlot(float) + def on_output_value_changed(self, value): + self._ui.line_edit_output_value.setText(str(value)) + + @pyqtSlot(bool) + def on_enable_reset_changed(self, value): + self._ui.push_button_reset.setEnabled(value)