From a7138a985bb0e2292f57a8261ef0243ad4682c22 Mon Sep 17 00:00:00 2001 From: Wannes Van Puyvelde Date: Thu, 18 Apr 2024 14:57:22 +0200 Subject: [PATCH] Threading fix: Timers are now in a seperate thread --- main.py | 12 ++++-------- serialcom/connect.py | 36 +++++++++++++++++++++--------------- serialcom/temperature.py | 4 ++++ thread/timer_worker.py | 19 +++++++++++++++++++ 4 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 thread/timer_worker.py diff --git a/main.py b/main.py index 9b012c1..f0292e1 100644 --- a/main.py +++ b/main.py @@ -38,6 +38,10 @@ def __init__(self): self.worker = None self.worker_thread = None + # Initialize timer_worker and thread + self.timer_worker = None + self.timer_worker_thread = None + signal_manager = SignalManager() # Connect the signal to a slot for updating the UI @@ -51,14 +55,6 @@ def __init__(self): # Call the function to search for connected devices find_connected_devices(self) - # Create the timers for reading temperature and sensor units - self.temp_timer = QTimer(self) - self.temp_timer.setInterval(2000) # Update every 10 seconds - self.temp_timer.timeout.connect(lambda: read_temperature(self, signal_manager)) - self.sensor_timer = QTimer(self) - self.sensor_timer.setInterval(2000) # Update every 10 seconds - self.sensor_timer.timeout.connect(lambda: read_sensor_units(self, signal_manager)) - def update_ui_slot(self, element_str, command, value): # Convert the string identifier to the correct UI element reference ui_element = self.find_ui_element(element_str) diff --git a/serialcom/connect.py b/serialcom/connect.py index aa3d01a..fd599f0 100644 --- a/serialcom/connect.py +++ b/serialcom/connect.py @@ -4,9 +4,9 @@ from serialcom.profibus import read_address, read_slot_count, read_slots, handle_address_change, handle_slot_count_change, profibus_connect_combobox from serialcom.sensor import read_input_names, read_sensor_setup, sensor_connect_type_combobox, sensor_connect_name_edit, sensor_connect_power_combobox, sensor_connect_combobox from serialcom.curve import read_curves, curve_connect_delete_button, curve_connect_curve_combobox -from serialcom.temperature import read_temperature, read_sensor_units from PySide6.QtCore import QThread from thread.worker import Worker +from thread.timer_worker import TimerWorker def find_connected_devices(main_window): try: @@ -38,9 +38,14 @@ def handle_disconnect(main_window): if main_window.ser == '': return try: + # Perform cleanup when the temperature_worker has finished its task + if main_window.timer_worker_thread and main_window.timer_worker_thread.isRunning(): + main_window.timer_worker_thread.quit() + main_window.timer_worker_thread.wait() + main_window.timer_worker_thread = None + main_window.timer_worker = None + main_window.ser.close() - main_window.temp_timer.stop() - main_window.sensor_timer.stop() # Disconnect signals main_window.general_ui.module_name_label.editingFinished.disconnect() @@ -83,13 +88,11 @@ def read_serial(main_window, signal_manager): read_input_names(main_window, signal_manager) read_curves(main_window, signal_manager) read_sensor_setup(main_window, signal_manager) - read_temperature(main_window, signal_manager) - read_sensor_units(main_window, signal_manager) except Exception as e: print(f"Error: {e}") -def connect_signals(main_window): +def connect_signals(main_window, signal_manager): try: # Connect signals main_window.general_ui.module_name_label.editingFinished.connect(lambda: handle_module_name_change(main_window)) @@ -112,8 +115,7 @@ def connect_signals(main_window): sensor_connect_combobox(main_window.sensor_ui.display_units_comboboxes[i], main_window, i) curve_connect_delete_button(main_window.curve_ui.delete_buttons[i], main_window, i) curve_connect_curve_combobox(main_window.curve_ui.curve_comboboxes[i], main_window, i) - - main_window.connection_ui.status_label.setText("Status: Connected") + signal_manager.update_ui("connection_ui.status_label", "setText", "Status: Connected") except Exception as e: print(f"Error: {e}") @@ -124,14 +126,14 @@ def handle_connect(main_window, signal_manager): main_window.worker = Worker(main_window, signal_manager) main_window.worker_thread = QThread() main_window.worker.moveToThread(main_window.worker_thread) - main_window.worker.finished_signal.connect(lambda: handle_worker_finished(main_window)) + main_window.worker.finished_signal.connect(lambda: handle_worker_finished(main_window, signal_manager)) main_window.worker_thread.started.connect(main_window.worker.run) - main_window.worker.start_timers_signal.connect(lambda: start_timers(main_window)) + main_window.worker.start_timers_signal.connect(lambda: start_timer(main_window, signal_manager)) main_window.worker_thread.start() except Exception as e: print(f"Error: {e}") -def handle_worker_finished(main_window): +def handle_worker_finished(main_window, signal_manager): try: # Perform cleanup when the worker has finished its task if main_window.worker_thread and main_window.worker_thread.isRunning(): @@ -139,10 +141,14 @@ def handle_worker_finished(main_window): main_window.worker_thread.wait() main_window.worker_thread = None main_window.worker = None - connect_signals(main_window) + connect_signals(main_window, signal_manager) except Exception as e: print(f"Error: {e}") -def start_timers(main_window): - main_window.temp_timer.start() - main_window.sensor_timer.start() \ No newline at end of file +def start_timer(main_window, signal_manager): + # Create new timer_worker and thread + main_window.timer_worker = TimerWorker(main_window, signal_manager) + main_window.timer_worker_thread = QThread() + main_window.timer_worker.moveToThread(main_window.timer_worker_thread) + main_window.timer_worker_thread.started.connect(main_window.timer_worker.run) + main_window.timer_worker_thread.start() \ No newline at end of file diff --git a/serialcom/temperature.py b/serialcom/temperature.py index 918d8f7..6273dd7 100644 --- a/serialcom/temperature.py +++ b/serialcom/temperature.py @@ -1,6 +1,10 @@ from PySide6.QtWidgets import QTableWidgetItem from PySide6.QtCore import QThread +def read_readings(main_window, signal_manager): + read_temperature(main_window, signal_manager) + read_sensor_units(main_window, signal_manager) + def read_temperature(main_window, signal_manager): try: # Write data to the port to ask temperature in Kelvin diff --git a/thread/timer_worker.py b/thread/timer_worker.py new file mode 100644 index 0000000..2a9a3b9 --- /dev/null +++ b/thread/timer_worker.py @@ -0,0 +1,19 @@ +from PySide6.QtCore import QObject, QTimer + +class TimerWorker(QObject): + def __init__(self, main_window, signal_manager): + super().__init__() + self.main_window = main_window + self.signal_manager = signal_manager + + def run(self): + from serialcom.temperature import read_temperature, read_sensor_units + self.temp_timer = QTimer(self) + self.temp_timer.setInterval(2000) # Update every 2 seconds + self.temp_timer.timeout.connect(lambda: read_temperature(self.main_window, self.signal_manager)) + self.temp_timer.start() + + self.sensor_timer = QTimer(self) + self.sensor_timer.setInterval(2000) # Update every 2 seconds + self.sensor_timer.timeout.connect(lambda: read_sensor_units(self.main_window, self.signal_manager)) + self.sensor_timer.start()