Skip to content

Commit 9588480

Browse files
Merge pull request #12 from AndreWohnsland/dev
Add proper plot alignement, migrate to qt6
2 parents db22a8c + e290e1a commit 9588480

21 files changed

Lines changed: 587 additions & 472 deletions

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,21 @@ python = ">=3.10,<3.12"
1212
GitPython = "^3.1.43"
1313
matplotlib = "^3.9.0"
1414
pandas = "^2.2.2"
15-
PyQt5 = "5.15.7"
1615
pyqt5-qt5 = "5.15.2"
1716
xlsxwriter = "^3.2.0"
1817
pyqtdarktheme = "^2.1.0"
1918
qtawesome = "^1.3.1"
2019
holidays = "^0.47"
2120
dataclasses-json = "^0.6.4"
21+
pyqt6 = "^6.4.2"
2222

2323
[tool.poetry.group.dev.dependencies]
2424
pyinstaller = "^6.8.0"
2525
pip-chill = "^1.0.3"
2626
jupyterlab = "^4.2.2"
2727
mypy = "^1.10.0"
2828
ruff = "^0.4.8"
29+
pyqt6-tools = "^6.4.2.3.3"
2930

3031
[build-system]
3132
requires = ["poetry-core"]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
gitpython
22
matplotlib
33
pandas
4-
pyqt5
4+
pyqt6
55
xlsxwriter
66
pyqtdarktheme
77
qtawesome

runme.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import logging
77
import sys
88

9-
from PyQt5.QtWidgets import QApplication
9+
from PyQt6.QtWidgets import QApplication
1010

1111
from src.ui_mainwindow import MainWindow
1212
from src.utils import get_additional_run_args, sync_theme
@@ -19,12 +19,12 @@
1919
app = QApplication(sys.argv + get_additional_run_args())
2020
w = MainWindow()
2121
# in case of active style change, also change theme, need to sync at start
22-
app.paletteChanged.connect(sync_theme)
22+
# app.paletteChanged.connect(sync_theme)
2323
# still keep the app running, even if the main window is closed (we use tray for the app)
2424
QApplication.setQuitOnLastWindowClosed(False)
2525
sync_theme()
2626
w.show()
27-
sys.exit(app.exec_())
27+
sys.exit(app.exec())
2828
except Exception as e:
2929
logger.exception(e)
3030
raise

scripts/compile_ui_to_python.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ $files = @(
66
)
77

88
foreach ($f in $files) {
9-
pyuic5 -x .\$f.ui -o .\$f.py
9+
pyuic6 -x .\$f.ui -o .\$f.py
1010
}
1111

1212
cd ..

scripts/plotting.ipynb

Lines changed: 65 additions & 14 deletions
Large diffs are not rendered by default.

src/config_handler.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
"country": "US",
1818
"subdiv": None,
1919
"workdays": [0, 1, 2, 3, 4], # 0-6, 0=Monday, 6=Sunday
20+
"plot_pause": True,
2021
}
21-
CONFIG_NAMES = Literal["name", "save_path", "country", "subdiv", "daily_hours", "weekly_hours", "workdays"]
22+
CONFIG_NAMES = Literal[
23+
"name", "save_path", "country", "subdiv", "daily_hours", "weekly_hours", "workdays", "plot_pause"
24+
]
2225

2326

2427
@dataclass
@@ -31,6 +34,7 @@ class Config:
3134
country: str
3235
subdiv: str | None
3336
workdays: list[int]
37+
plot_pause: bool
3438

3539
@classmethod
3640
def from_kwargs(cls, **kwargs):

src/datastore.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def _generate_monthly_time(
104104
daily_minutes = CONFIG_HANDLER.config.daily_hours * 60
105105
for _day in full_month:
106106
days_data = df[df["date"] == _day.date()]
107-
calculated_time = 1.0
107+
calculated_time = 0.0
108108
# when we got a free day, we get the working time for this day
109109
if _day.date() in free_days:
110110
calculated_time += daily_minutes

src/icons.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from dataclasses import dataclass
22

33
import qtawesome as qta
4-
from PyQt5.QtGui import QIcon
4+
from PyQt6.QtGui import QIcon
55

66
from src.utils import get_background_color, get_font_color
77

src/ui_config_window.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
from typing import TYPE_CHECKING
44

55
import holidays
6-
from PyQt5.QtCore import Qt
7-
from PyQt5.QtWidgets import QWidget
6+
from PyQt6.QtCore import Qt
7+
from PyQt6.QtWidgets import QWidget
88

99
from src.config_handler import CONFIG_HANDLER
1010
from src.icons import get_app_icon
@@ -21,8 +21,13 @@ def __init__(self, main_window: MainWindow):
2121
self.main_window = main_window
2222
self.setupUi(self)
2323
self.setWindowIcon(get_app_icon())
24-
self.setWindowFlags(Qt.Window | Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint) # type: ignore
25-
self.setAttribute(Qt.WA_DeleteOnClose) # type: ignore
24+
self.setWindowFlags(
25+
Qt.WindowType.Window
26+
| Qt.WindowType.CustomizeWindowHint
27+
| Qt.WindowType.WindowTitleHint
28+
| Qt.WindowType.WindowCloseButtonHint
29+
)
30+
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
2631
self.country_list = holidays.list_supported_countries()
2732
self._update_country_list()
2833
self.set_config_values()
@@ -71,6 +76,7 @@ def set_config_values(self):
7176
self.input_name.setText(CONFIG_HANDLER.config.name)
7277
self.input_daily_hours.setValue(CONFIG_HANDLER.config.daily_hours)
7378
self.input_weekly_hours.setValue(CONFIG_HANDLER.config.weekly_hours)
79+
self.input_plot_pause.setChecked(CONFIG_HANDLER.config.plot_pause)
7480
for day in CONFIG_HANDLER.config.workdays:
7581
getattr(self, f"radio_weekday_{day}").setChecked(True)
7682

@@ -81,6 +87,7 @@ def apply_config(self):
8187
CONFIG_HANDLER.config.name = self.input_name.text()
8288
CONFIG_HANDLER.config.daily_hours = self.input_daily_hours.value()
8389
CONFIG_HANDLER.config.weekly_hours = self.input_daily_hours.value()
90+
CONFIG_HANDLER.config.plot_pause = self.input_plot_pause.isChecked()
8491
selected_days: list[int] = []
8592
for day in range(7):
8693
if getattr(self, f"radio_weekday_{day}").isChecked():

src/ui_controller.py

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from PyQt5.QtWidgets import QDialog, QFileDialog, QInputDialog, QLayout, QMessageBox, QTableWidget, QTableWidgetItem
1+
from PyQt6.QtWidgets import QDialog, QFileDialog, QInputDialog, QLayout, QMessageBox, QTableWidget, QTableWidgetItem
22

33
from src import __version__
4-
from src.config_handler import CONFIG_HANDLER, CONFIG_NAMES
4+
from src.config_handler import CONFIG_HANDLER
55
from src.filepath import HOME_PATH
66
from src.icons import get_app_icon
77

@@ -13,12 +13,12 @@ def __init__(self):
1313
def show_message(self, message: str):
1414
"""Prompt default messagebox, use a QMessageBox with OK-Button."""
1515
message_box = QMessageBox()
16-
message_box.setStandardButtons(QMessageBox.Ok) # type: ignore
16+
message_box.setStandardButtons(QMessageBox.StandardButton.Ok)
1717
message_box.setText(str(message))
1818
message_box.setWindowIcon(get_app_icon())
1919
message_box.setWindowTitle("Information")
2020
message_box.show()
21-
message_box.exec_()
21+
message_box.exec()
2222

2323
def report_choice(self):
2424
message_box = QMessageBox()
@@ -27,11 +27,11 @@ def report_choice(self):
2727
)
2828
message_box.setWindowTitle("Report Generation")
2929
message_box.setWindowIcon(get_app_icon())
30-
overtime_button = message_box.addButton("Overtime", QMessageBox.YesRole) # type: ignore
31-
time_button = message_box.addButton("Time", QMessageBox.NoRole) # type: ignore
32-
message_box.addButton("Cancel", QMessageBox.RejectRole) # type: ignore
30+
overtime_button = message_box.addButton("Overtime", QMessageBox.ButtonRole.YesRole)
31+
time_button = message_box.addButton("Time", QMessageBox.ButtonRole.NoRole)
32+
message_box.addButton("Cancel", QMessageBox.ButtonRole.RejectRole)
3333

34-
message_box.exec_()
34+
message_box.exec()
3535
if message_box.clickedButton() == overtime_button:
3636
return True
3737
if message_box.clickedButton() == time_button:
@@ -43,9 +43,9 @@ def user_okay(self, text: str):
4343
message_box.setText(text)
4444
message_box.setWindowTitle("Confirmation required")
4545
message_box.setWindowIcon(get_app_icon())
46-
yes_button = message_box.addButton("Yes", QMessageBox.YesRole) # type: ignore
47-
message_box.addButton("No", QMessageBox.NoRole) # type: ignore
48-
message_box.exec_()
46+
yes_button = message_box.addButton("Yes", QMessageBox.ButtonRole.YesRole)
47+
message_box.addButton("No", QMessageBox.ButtonRole.NoRole)
48+
message_box.exec()
4949
if message_box.clickedButton() == yes_button:
5050
return True
5151
return False
@@ -66,11 +66,11 @@ def get_folder(self, current_path: str, parent=None):
6666
current_path = str(HOME_PATH)
6767

6868
dialog = QFileDialog(parent)
69-
dialog.setFileMode(QFileDialog.DirectoryOnly) # type: ignore
69+
dialog.setFileMode(QFileDialog.FileMode.Directory)
7070
dialog.setDirectory(current_path)
7171

72-
if dialog.exec_() == QDialog.Accepted: # type: ignore
73-
return dialog.selectedFiles()[0] # returns a list
72+
if dialog.exec() == QDialog.DialogCode.Accepted:
73+
return dialog.selectedFiles()[0]
7474
return ""
7575

7676
def fill_table(self, table: QTableWidget, entry):
@@ -91,17 +91,6 @@ def set_header_names(self, table: QTableWidget, name1: str, name2: str):
9191
if header_2 is not None:
9292
header_2.setText(name2)
9393

94-
def get_user_data(self, parent):
95-
needed_keys: list[CONFIG_NAMES] = ["name"]
96-
# todo adjust to new class logic
97-
for data in needed_keys:
98-
text, ok = self.get_text(data, parent)
99-
if not ok:
100-
return
101-
if text != "":
102-
CONFIG_HANDLER.set_config_value(data, text, write=False)
103-
CONFIG_HANDLER.write_config_file()
104-
10594
def get_save_folder(self):
10695
user_path = CONFIG_HANDLER.config.save_path
10796
returned_path = self.get_folder(user_path)

0 commit comments

Comments
 (0)