diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f9e0fd0 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +.PHONY: nuitka clean env + +#export CCFLAGS += -O1 +#export CXXFLAGS += -O1 + +nuitka: + poetry run python -m nuitka --standalone --onefile --enable-plugin=pyqt5 --output-dir=build/nuitka timebot/app.py + +env: + env + +clean: + rm -rf dist + rm -rf build diff --git a/timebot/gui.py b/timebot/gui.py index 899d72f..2e5ef57 100644 --- a/timebot/gui.py +++ b/timebot/gui.py @@ -1,11 +1,14 @@ import datetime +import logging from PyQt5 import QtGui -from PyQt5.QtCore import QTimer, QObject, pyqtSignal, QThread -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QLabel, QMessageBox, QInputDialog, QLineEdit +from PyQt5.QtCore import QTimer, QObject, pyqtSignal, QThread, Qt +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QLabel, QMessageBox, QInputDialog, QLineEdit, QHBoxLayout from timebot.timebot import TimeBot, TimebotObtainPasswordError +package_logger = logging.getLogger(__name__) + class TimebotApiWorker(QObject): status_msg = pyqtSignal(object) @@ -22,7 +25,7 @@ class TimebotApiWorker(QObject): try: hours_present = self.timebot.get_hours_present() hours_present = hours_present - datetime.timedelta(microseconds=hours_present.microseconds) - self.hours_present_msg.emit(str(hours_present)) + self.hours_present_msg.emit(hours_present) self.status_msg.emit(self.timebot.status()) except TimebotObtainPasswordError as e: self.obtain_password.emit() @@ -31,6 +34,22 @@ class TimebotApiWorker(QObject): self.finished.emit() +class HoursPresentLabelArea(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + + self.text_box_hours_present_label = QLabel() + self.text_box_hours_present_label.setText("Hours present:") + self.text_box_hours_present = QLabel() + self.text_box_hours_present.setStyleSheet("background : #E0E0E0") + self.text_box_hours_present.setAlignment(Qt.AlignCenter) + + layout = QHBoxLayout() + layout.addWidget(self.text_box_hours_present_label) + layout.addWidget(self.text_box_hours_present) + self.setLayout(layout) + + class TimebotMain(QWidget): def __init__(self, timebot: TimeBot, parent=None): super().__init__(parent) @@ -42,30 +61,29 @@ class TimebotMain(QWidget): self.setWindowIcon(QtGui.QIcon.fromTheme('face-devilish')) self.resize(300, 270) + self.hours_present = datetime.timedelta(microseconds=0) + self.text_box_status = QLabel() - self.text_box_hours_present = QLabel() + self.text_box_hours_present_area = HoursPresentLabelArea(parent=self) self.btn_update_status = QPushButton("Refresh Status") - self.btnPress2 = QPushButton("Button 2") layout = QVBoxLayout() layout.addWidget(self.text_box_status) - layout.addWidget(self.text_box_hours_present) + layout.addWidget(self.text_box_hours_present_area) layout.addWidget(self.btn_update_status) - layout.addWidget(self.btnPress2) self.setLayout(layout) self.btn_update_status.clicked.connect(self.update_status) - self.btnPress2.clicked.connect(self.btnPress2_Clicked) - self.status_timer_time = 29000 + self.status_timer_time = 60000 # msec -> 60s self.status_timer = QTimer() self.status_timer.timeout.connect(self.update_status) self.status_timer.start(self.status_timer_time) - # Timer to refresh the main window ... is needed to react on Ctrl+C + self.main_window_timer_time = 1000 # msec -> 1s self.main_window_timer = QTimer() - self.main_window_timer.timeout.connect(lambda: None) - self.main_window_timer.start(500) + self.main_window_timer.timeout.connect(self.update_main_window) + self.main_window_timer.start(self.main_window_timer_time) self.error_msg = QMessageBox() self.error_msg.setWindowTitle("Timebot ERROR") @@ -77,9 +95,21 @@ class TimebotMain(QWidget): self.update_status_running = False self.update_status() + def update_main_window(self): + self.main_window_info_thread = QThread() + self.main_window_info_worker = MainWindowInfoWorker() + self.main_window_info_worker.moveToThread(self.main_window_info_thread) + self.main_window_info_thread.started.connect(self.main_window_info_worker.run) + self.main_window_info_worker.finished.connect(self.main_window_info_thread.quit) + self.main_window_info_worker.finished.connect(self.main_window_info_worker.deleteLater) + self.main_window_info_thread.finished.connect(self.main_window_info_thread.deleteLater) + self.main_window_info_worker.finished.connect(self.update_hours_present) + self.main_window_info_thread.start() + def get_password(self, callback: callable = None): self.status_timer.stop() - password, ok = self.password_dialog.getText(self, "Timebot Password", 'Enter your password:', QLineEdit.Password) + password, ok = self.password_dialog.getText(self, "Timebot Password", 'Enter your password:', + QLineEdit.Password) if ok: self.timebot.mobatime_api.password = password try: @@ -108,6 +138,13 @@ class TimebotMain(QWidget): self.btn_update_status.setText("Refresh Status") self.update_status_running = False + def update_hours_present(self, override=None): + if override: + self.hours_present: datetime.timedelta = override + elif self.hours_present > datetime.timedelta(seconds=self.main_window_timer_time / 100): + self.hours_present = self.hours_present + datetime.timedelta(seconds=1) + self.text_box_hours_present_area.text_box_hours_present.setText(str(self.hours_present)) + def update_status(self): if self.update_status_running: return @@ -120,11 +157,15 @@ class TimebotMain(QWidget): self.status_thread.finished.connect(self.status_thread.deleteLater) self.status_thread.finished.connect(self.update_status_finished) self.status_worker.status_msg.connect(self.text_box_status.setText) - self.status_worker.hours_present_msg.connect(self.text_box_hours_present.setText) + self.status_worker.hours_present_msg.connect(lambda hp, *args: self.update_hours_present(override=hp)) self.status_worker.error.connect(lambda exp, *args: self.error_msg_show(str(exp))) self.status_worker.obtain_password.connect(lambda *args: self.get_password(self.update_status)) self.status_thread.start() self.update_status_started() - def btnPress2_Clicked(self): - pass + +class MainWindowInfoWorker(QObject): + finished = pyqtSignal() + + def run(self): + self.finished.emit()