Jun-03-2024, 05:00 PM
Hello, in this script i get an freezing window after i activate the checkbox IR raw:
Checkbox IR aktiviert
C:\Users\emanu\source\repos\PythonApplication3\PythonApplication3\plotter_live.py:142: RuntimeWarning: coroutine 'PlotterWindow.update_plot_data_no_filter' was never awaited
self.update_plot_data_no_filter()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Why? Here i have done the await: await asyncio.sleep(1.7)
Full code with async:
import pyqtgraph as pg from PyQt6.QtWidgets import QMainWindow, QDialog from PyQt6.QtGui import QAction from PyQt6 import uic import numpy as np import time from PyQt6 import QtWidgets, uic import sys from PyQt6.QtCore import Qt, pyqtSignal from filter_modul import smooth_data import time from PyQt6.QtCore import QThread, pyqtSignal from PyQt6.QtCore import QTimer SAMPE_ARRAY = 100 # Globale Variable zur Speicherung des aktuellen IR-Filters current_filter_IR = "no_filter" # Laden der UI-Datei für das Einstellung Fenster im Liveplotter uiclass, baseclass = uic.loadUiType("plotter_live_window.ui") # Laden der UI-Datei für das Einstellungsfenster das in dem Liveplotter Fenster - Menü geöffnet wird einstellung_ui_file = "liveplotter_einstellungen.ui" einstellung_ui, einstellung_base = uic.loadUiType(einstellung_ui_file) # Laden der UI-Datei für das Einstellungsfenster das in dem Liveplotter Fenster - Menü geöffnet wird filter_ir_ui_file = "filter_live_plotter_ir.ui" filter_ir_ui, filter_ir_base = uic.loadUiType(filter_ir_ui_file) class FilterIRWindow(filter_ir_base, filter_ir_ui): def __init__(self): super().__init__() self.ui = uic.loadUi("filter_live_plotter_ir.ui") self.setupUi(self) class LiveplotterEinstellungenWindow(einstellung_base, einstellung_ui): checkbox_ir_state_changed = pyqtSignal(bool) def __init__(self): super().__init__() self.ui = uic.loadUi("liveplotter_einstellungen.ui") self.setupUi(self) self.actionIR.triggered.connect(self.filter_ir_fenster_clicked) self.ui.menubar.addAction(self.actionIR) # Hinzufügen der Aktion zum Menü self.checkbox_ir.stateChanged.connect(self.plot_data_checkbox_ir_state_changed) def plot_data_checkbox_ir_state_changed(self, state): self.checkbox_ir_state_changed.emit(state) def filter_ir_fenster_clicked(self): print("Filter IR gedrückt") self.filter_ir_fenster = FilterIRWindow() self.filter_ir_fenster.show() self.filter_ir_fenster.pushButton.clicked.connect(self.apply_filters_IR) # Verknüpfen des Buttons Update im Fenster IR Filter mit der Funktion die die Variable updatet def apply_filters_IR(self): global current_filter_IR print("Update Button in IR Filter geklickt") # Funktion zum Anwenden der ausgewählten Filter current_text = self.filter_ir_fenster.filter_ir_comobox_1.currentText() if current_text == "Mittelwertfilter": current_filter_IR = "mean_filter" else: current_filter_IR = "no_filter" print("Filter angewendet für IR:", current_filter_IR) class PlotterWindow(baseclass, uiclass): def __init__(self, df): super().__init__() # Laden der UI-Datei ui_file = "plotter_live_window.ui" ui = uic.loadUi(ui_file) self.plot_item = None self.setupUi(self) self.actionAktualisieren.triggered.connect(self.update_button_plotter) self.data = [0] * SAMPE_ARRAY self.timer = pg.QtCore.QTimer() self.liveplotterEinstellungen.triggered.connect(self.einstellungen_klicked) einstellungs_fenster = LiveplotterEinstellungenWindow() einstellungs_fenster.checkbox_ir_state_changed.connect(self.checkbox_ir_state_changed) self.checkbox_state_ir = False self.data_updater = DataUpdater(df) # Instanziierung der DataUpdater-Klasse self.data_updater.data_updated.connect(self.on_data_updated) # Verbindet die Funktion on_dat_updated mit data_updater self.data_updater.start() # Diese Methode wird aufgerufen, jedes Mal wenn das Signal data_updated von DataUpdater emittiert wird. # Sie aktualisiert list_data_ir_puffer in PlotterWindow, so dass die neuesten Daten von DataUpdater verfügbar sind. def on_data_updated(self): self.list_data_ir_puffer = self.data_updater.list_data_ir_puffer def closeEvent(self, event): # Stoppen des DataUpdater-Threads beim Schließen des Fensters self.data_updater.stop() self.data_updater.wait() super().closeEvent(event) def checkbox_ir_state_changed(self, state): # Hier können Sie den Wert 'state' verwenden, der von der Checkbox im Einstellungsfenster übergeben wurde print("IR Checkbox Zustand geändert:", state) self.checkbox_state_ir = state if state: # Wenn die Checkbox aktiviert ist print("IR Checkbox aktiviert, Daten werden aktualisiert...") #Prüft ob der Aktuelle Filter für das IR Signal aus ist und plottet dann die Rohdaten if current_filter_IR == "no_filter": self.update_plot_data_no_filter() if current_filter_IR == "mean_filter": self.update_plot_data_mean_filter() def checkbox_ir_state_changed(self, state): global current_filter_IR print("Checkbox IR aktiviert") #Prüft ob der Aktuelle Filter für das IR Signal aus ist und plottet dann die Rohdaten if current_filter_IR == "no_filter": self.update_plot_data_no_filter() if current_filter_IR == "mean_filter": self.update_plot_data_mean_filter() def plot_data_checkbox_ir_state_changed(self, state): if state: # Checkbox ist aktiviert, Live-Daten plotten print("IR Checkbox on, Program ist in Plotter Window plot_data_checkbox_ir_state_changed") self.update_plot_data() else: # Checkbox ist deaktiviert, Live-Daten nicht plotten pass def plot(self, df): self.plot_item = self.graphWidget.plot(self.data, pen='w') # Erstellen des Plot-Items #Updatet Plottdaten für IR Werte ohne Filter ''' def update_plot_data_no_filter(self): global list_data_ir_puffer global SAMPE_ARRAY # Erhalte die ersten 100 Datenpunkte aus der Liste data_to_plot_IR = self.data_updater.list_data_ir_puffer[:SAMPE_ARRAY] index = 0 # Startindex für den Datenabruf for data_point_IR in data_to_plot_IR: #data_point: Diese Variable repräsentiert jeden einzelnen Datenpunkt, der während der Iteration durch data_to_plot geplottet wird. print(f"Datenpunkt {index + 1}: {data_point_IR}") # Datenpunkt printen self.data = np.roll(self.data, -1) self.data[-1] = data_point_IR self.plot_item.setData(y=self.data) # Aktualisieren der Daten des Plot-Items pg.QtCore.QCoreApplication.processEvents() # Aktualisieren des Plot-Widgets time.sleep(0.017) # Pause von 10 Millisekunden index += 1 # Entferne die geplotteten Datenpunkte aus der Liste self.data_updater.list_data_ir_puffer = self.data_updater.list_data_ir_puffer[SAMPE_ARRAY:] ''' def update_plot_data_no_filter(self): global SAMPE_ARRAY while True: # Schleife wird ausgeführt, solange die Checkbox aktiviert ist # Erhalte die ersten 100 Datenpunkte aus der Liste self.data_to_plot_IR = self.data_updater.list_data_ir_puffer[:SAMPE_ARRAY] print("Daten zum Plotten:", self.data_to_plot_IR) # Verzögerung von 1700 ms time.sleep(1.7) # Lösche die ersten 100 Datenpunkte self.data_updater.list_data_ir_puffer = self.data_updater.list_data_ir_puffer[SAMPE_ARRAY:] def update_plot_data_mean_filter(self): print("Update Plot Data Mittelwert") from safe_to_excel import df IR_raw_list = df['Red'].tail(SAMPE_ARRAY).astype(float) # Gibt die letzten 100 Werte aus IR_raw_list.reset_index(drop=True, inplace=True) # Setze den Index zurück, damit beginnen wir beim Index 0 # Daten glätten, wobei der vorherige remainder verwendet wird IR_smooth_list, self.remainder = smooth_data(IR_raw_list, getattr(self, 'remainder', None)) # Geplättete Daten plotten self.plot_smoothed_data(IR_smooth_list) # Funktion die die gefilterten IR Daten (Mittelwert) plottet def plot_smoothed_data(self, smoothed_data): index = 0 # Startindex für den Datenabruf while index < SAMPE_ARRAY: data_point = smoothed_data[index] # Datenpunkt für den aktuellen Index print(f"Glätteter Datenpunkt {index + 1}: {data_point}") # Datenpunkt printen self.data = np.roll(self.data, -1) # Verschiebt oder rollt die Elemente des Arrays um eine Position self.data[-1] = data_point # Setzt den Datenpunkt an das Ende des Arrays self.plot_item.setData(y=self.data) # Aktualisieren der Daten des Plot-Items pg.QtCore.QCoreApplication.processEvents() # Aktualisieren des Plot-Widgets time.sleep(0.017) # Pause von 10 Millisekunden index += 1 def update_button_plotter(self): einstellungs_fenster = LiveplotterEinstellungenWindow() einstellungs_fenster.show() def keyPressEvent(self, event): if event.key() == Qt.Key.Key_F5: self.update_button_plotter() else: super().keyPressEvent(event) def einstellungen_klicked(self): print("Einstellungen in Liveplotter gedrückt") self.einstellungs_fenster = LiveplotterEinstellungenWindow() self.einstellungs_fenster.checkbox_ir.stateChanged.connect(self.checkbox_ir_state_changed) self.einstellungs_fenster.show() # Wenn sich die Comobox (Dropdown Menü) im Fenster IR Filter verändert, dann printet er den ausgewählten Filter class FilterIRWindow(filter_ir_base, filter_ir_ui): def __init__(self): super().__init__() self.ui = uic.loadUi("filter_live_plotter_ir.ui") self.setupUi(self) self.filter_ir_comobox_1.currentIndexChanged.connect(self.comboBox_changed) def comboBox_changed(self, index): current_text = self.filter_ir_comobox_1.currentText() if current_text == "Mittelwertfilter": print("Mittelwertfilter ausgewählt für IR ") # Hier kannst du die Daten mit dem Mittelwertfilter verarbeiten if current_text == "Kein Filter": print("Kein Filter ausgewählt für IR") # Hier kannst du die Daten mit dem Mittelwertfilter verarbeiten class DataUpdater(QThread): data_updated = pyqtSignal() def __init__(self, df): super().__init__() self.df = df self.df_old = None # DataFrame zur Überprüfung auf Änderungen self.list_data_ir_puffer = [] # Liste für neue Daten def run(self): print("DataUpdater Thread gestartet") # Ausgabe, wenn der Thread gestartet wird while True: # Überprüfen, ob neue Daten verfügbar sind df_new = self.df_update() # Aktualisiere den DataFrame if not df_new.equals(self.df_old): # Neue Daten vorhanden self.list_data_ir_puffer += df_new['Red'].tail(SAMPE_ARRAY).astype(float).tolist() self.df_old = df_new if len(self.list_data_ir_puffer) > 500: print("Die Anzahl der Einträge in der Liste IR Puffer ist größer als 500.") # Signal senden, um anzuzeigen, dass neue Daten verfügbar sind self.data_updated.emit() time.sleep(0.1) # Beispiel: Wartezeit von 0.1 Sekunden def df_update(self): from safe_to_excel import df return df.copy() def stop(self): self.running = False print("Data Updater Thread geschlossen") def stop(self): self.running = False print("Date Updater Thread geschlossen")To fix this i have tried to make the function async:
async def update_plot_data_no_filter(self): global SAMPE_ARRAY while True: # Schleife wird ausgeführt, solange die Checkbox aktiviert ist # Erhalte die ersten 100 Datenpunkte aus der Liste self.data_to_plot_IR = self.data_updater.list_data_ir_puffer[:SAMPE_ARRAY] print("Daten zum Plotten:", self.data_to_plot_IR) # Verzögerung von 1700 ms await asyncio.sleep(1.7) # Lösche die ersten 100 Datenpunkte self.data_updater.list_data_ir_puffer = self.data_updater.list_data_ir_puffer[SAMPE_ARRAY:]On the End of the program i open the loop with:
async def main(): pass # non blocking program if __name__ == "__main__": asyncio.run(main())But i get this error:
Checkbox IR aktiviert
C:\Users\emanu\source\repos\PythonApplication3\PythonApplication3\plotter_live.py:142: RuntimeWarning: coroutine 'PlotterWindow.update_plot_data_no_filter' was never awaited
self.update_plot_data_no_filter()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Why? Here i have done the await: await asyncio.sleep(1.7)
Full code with async:
import pyqtgraph as pg from PyQt6.QtWidgets import QMainWindow, QDialog from PyQt6.QtGui import QAction from PyQt6 import uic import numpy as np import time from PyQt6 import QtWidgets, uic import sys from PyQt6.QtCore import Qt, pyqtSignal from filter_modul import smooth_data import time from PyQt6.QtCore import QThread, pyqtSignal from PyQt6.QtCore import QTimer import asyncio SAMPE_ARRAY = 100 # Globale Variable zur Speicherung des aktuellen IR-Filters current_filter_IR = "no_filter" # Laden der UI-Datei für das Einstellung Fenster im Liveplotter uiclass, baseclass = uic.loadUiType("plotter_live_window.ui") # Laden der UI-Datei für das Einstellungsfenster das in dem Liveplotter Fenster - Menü geöffnet wird einstellung_ui_file = "liveplotter_einstellungen.ui" einstellung_ui, einstellung_base = uic.loadUiType(einstellung_ui_file) # Laden der UI-Datei für das Einstellungsfenster das in dem Liveplotter Fenster - Menü geöffnet wird filter_ir_ui_file = "filter_live_plotter_ir.ui" filter_ir_ui, filter_ir_base = uic.loadUiType(filter_ir_ui_file) class FilterIRWindow(filter_ir_base, filter_ir_ui): def __init__(self): super().__init__() self.ui = uic.loadUi("filter_live_plotter_ir.ui") self.setupUi(self) class LiveplotterEinstellungenWindow(einstellung_base, einstellung_ui): checkbox_ir_state_changed = pyqtSignal(bool) def __init__(self): super().__init__() self.ui = uic.loadUi("liveplotter_einstellungen.ui") self.setupUi(self) self.actionIR.triggered.connect(self.filter_ir_fenster_clicked) self.ui.menubar.addAction(self.actionIR) # Hinzufügen der Aktion zum Menü self.checkbox_ir.stateChanged.connect(self.plot_data_checkbox_ir_state_changed) def plot_data_checkbox_ir_state_changed(self, state): self.checkbox_ir_state_changed.emit(state) def filter_ir_fenster_clicked(self): print("Filter IR gedrückt") self.filter_ir_fenster = FilterIRWindow() self.filter_ir_fenster.show() self.filter_ir_fenster.pushButton.clicked.connect(self.apply_filters_IR) # Verknüpfen des Buttons Update im Fenster IR Filter mit der Funktion die die Variable updatet def apply_filters_IR(self): global current_filter_IR print("Update Button in IR Filter geklickt") # Funktion zum Anwenden der ausgewählten Filter current_text = self.filter_ir_fenster.filter_ir_comobox_1.currentText() if current_text == "Mittelwertfilter": current_filter_IR = "mean_filter" else: current_filter_IR = "no_filter" print("Filter angewendet für IR:", current_filter_IR) class PlotterWindow(baseclass, uiclass): def __init__(self, df): super().__init__() # Laden der UI-Datei ui_file = "plotter_live_window.ui" ui = uic.loadUi(ui_file) self.plot_item = None self.setupUi(self) self.actionAktualisieren.triggered.connect(self.update_button_plotter) self.data = [0] * SAMPE_ARRAY self.timer = pg.QtCore.QTimer() self.liveplotterEinstellungen.triggered.connect(self.einstellungen_klicked) einstellungs_fenster = LiveplotterEinstellungenWindow() einstellungs_fenster.checkbox_ir_state_changed.connect(self.checkbox_ir_state_changed) self.checkbox_state_ir = False self.data_updater = DataUpdater(df) # Instanziierung der DataUpdater-Klasse self.data_updater.data_updated.connect(self.on_data_updated) # Verbindet die Funktion on_dat_updated mit data_updater self.data_updater.start() # Diese Methode wird aufgerufen, jedes Mal wenn das Signal data_updated von DataUpdater emittiert wird. # Sie aktualisiert list_data_ir_puffer in PlotterWindow, so dass die neuesten Daten von DataUpdater verfügbar sind. def on_data_updated(self): self.list_data_ir_puffer = self.data_updater.list_data_ir_puffer def closeEvent(self, event): # Stoppen des DataUpdater-Threads beim Schließen des Fensters self.data_updater.stop() self.data_updater.wait() super().closeEvent(event) def checkbox_ir_state_changed(self, state): # Hier können Sie den Wert 'state' verwenden, der von der Checkbox im Einstellungsfenster übergeben wurde print("IR Checkbox Zustand geändert:", state) self.checkbox_state_ir = state if state: # Wenn die Checkbox aktiviert ist print("IR Checkbox aktiviert, Daten werden aktualisiert...") #Prüft ob der Aktuelle Filter für das IR Signal aus ist und plottet dann die Rohdaten if current_filter_IR == "no_filter": self.update_plot_data_no_filter() if current_filter_IR == "mean_filter": self.update_plot_data_mean_filter() def checkbox_ir_state_changed(self, state): global current_filter_IR print("Checkbox IR aktiviert") #Prüft ob der Aktuelle Filter für das IR Signal aus ist und plottet dann die Rohdaten if current_filter_IR == "no_filter": self.update_plot_data_no_filter() if current_filter_IR == "mean_filter": self.update_plot_data_mean_filter() def plot_data_checkbox_ir_state_changed(self, state): if state: # Checkbox ist aktiviert, Live-Daten plotten print("IR Checkbox on, Program ist in Plotter Window plot_data_checkbox_ir_state_changed") self.update_plot_data() else: # Checkbox ist deaktiviert, Live-Daten nicht plotten pass def plot(self, df): self.plot_item = self.graphWidget.plot(self.data, pen='w') # Erstellen des Plot-Items #Updatet Plottdaten für IR Werte ohne Filter ''' def update_plot_data_no_filter(self): global list_data_ir_puffer global SAMPE_ARRAY # Erhalte die ersten 100 Datenpunkte aus der Liste data_to_plot_IR = self.data_updater.list_data_ir_puffer[:SAMPE_ARRAY] index = 0 # Startindex für den Datenabruf for data_point_IR in data_to_plot_IR: #data_point: Diese Variable repräsentiert jeden einzelnen Datenpunkt, der während der Iteration durch data_to_plot geplottet wird. print(f"Datenpunkt {index + 1}: {data_point_IR}") # Datenpunkt printen self.data = np.roll(self.data, -1) self.data[-1] = data_point_IR self.plot_item.setData(y=self.data) # Aktualisieren der Daten des Plot-Items pg.QtCore.QCoreApplication.processEvents() # Aktualisieren des Plot-Widgets time.sleep(0.017) # Pause von 10 Millisekunden index += 1 # Entferne die geplotteten Datenpunkte aus der Liste self.data_updater.list_data_ir_puffer = self.data_updater.list_data_ir_puffer[SAMPE_ARRAY:] ''' async def update_plot_data_no_filter(self): global SAMPE_ARRAY while True: # Schleife wird ausgeführt, solange die Checkbox aktiviert ist # Erhalte die ersten 100 Datenpunkte aus der Liste self.data_to_plot_IR = self.data_updater.list_data_ir_puffer[:SAMPE_ARRAY] print("Daten zum Plotten:", self.data_to_plot_IR) # Verzögerung von 1700 ms await asyncio.sleep(1.7) # Lösche die ersten 100 Datenpunkte self.data_updater.list_data_ir_puffer = self.data_updater.list_data_ir_puffer[SAMPE_ARRAY:] def update_plot_data_mean_filter(self): print("Update Plot Data Mittelwert") from safe_to_excel import df IR_raw_list = df['Red'].tail(SAMPE_ARRAY).astype(float) # Gibt die letzten 100 Werte aus IR_raw_list.reset_index(drop=True, inplace=True) # Setze den Index zurück, damit beginnen wir beim Index 0 # Daten glätten, wobei der vorherige remainder verwendet wird IR_smooth_list, self.remainder = smooth_data(IR_raw_list, getattr(self, 'remainder', None)) # Geplättete Daten plotten self.plot_smoothed_data(IR_smooth_list) # Funktion die die gefilterten IR Daten (Mittelwert) plottet def plot_smoothed_data(self, smoothed_data): index = 0 # Startindex für den Datenabruf while index < SAMPE_ARRAY: data_point = smoothed_data[index] # Datenpunkt für den aktuellen Index print(f"Glätteter Datenpunkt {index + 1}: {data_point}") # Datenpunkt printen self.data = np.roll(self.data, -1) # Verschiebt oder rollt die Elemente des Arrays um eine Position self.data[-1] = data_point # Setzt den Datenpunkt an das Ende des Arrays self.plot_item.setData(y=self.data) # Aktualisieren der Daten des Plot-Items pg.QtCore.QCoreApplication.processEvents() # Aktualisieren des Plot-Widgets time.sleep(0.017) # Pause von 10 Millisekunden index += 1 def update_button_plotter(self): einstellungs_fenster = LiveplotterEinstellungenWindow() einstellungs_fenster.show() def keyPressEvent(self, event): if event.key() == Qt.Key.Key_F5: self.update_button_plotter() else: super().keyPressEvent(event) def einstellungen_klicked(self): print("Einstellungen in Liveplotter gedrückt") self.einstellungs_fenster = LiveplotterEinstellungenWindow() self.einstellungs_fenster.checkbox_ir.stateChanged.connect(self.checkbox_ir_state_changed) self.einstellungs_fenster.show() # Wenn sich die Comobox (Dropdown Menü) im Fenster IR Filter verändert, dann printet er den ausgewählten Filter class FilterIRWindow(filter_ir_base, filter_ir_ui): def __init__(self): super().__init__() self.ui = uic.loadUi("filter_live_plotter_ir.ui") self.setupUi(self) self.filter_ir_comobox_1.currentIndexChanged.connect(self.comboBox_changed) def comboBox_changed(self, index): current_text = self.filter_ir_comobox_1.currentText() if current_text == "Mittelwertfilter": print("Mittelwertfilter ausgewählt für IR ") # Hier kannst du die Daten mit dem Mittelwertfilter verarbeiten if current_text == "Kein Filter": print("Kein Filter ausgewählt für IR") # Hier kannst du die Daten mit dem Mittelwertfilter verarbeiten class DataUpdater(QThread): data_updated = pyqtSignal() def __init__(self, df): super().__init__() self.df = df self.df_old = None # DataFrame zur Überprüfung auf Änderungen self.list_data_ir_puffer = [] # Liste für neue Daten def run(self): print("DataUpdater Thread gestartet") # Ausgabe, wenn der Thread gestartet wird while True: # Überprüfen, ob neue Daten verfügbar sind df_new = self.df_update() # Aktualisiere den DataFrame if not df_new.equals(self.df_old): # Neue Daten vorhanden self.list_data_ir_puffer += df_new['Red'].tail(SAMPE_ARRAY).astype(float).tolist() self.df_old = df_new if len(self.list_data_ir_puffer) > 500: print("Die Anzahl der Einträge in der Liste IR Puffer ist größer als 500.") # Signal senden, um anzuzeigen, dass neue Daten verfügbar sind self.data_updated.emit() time.sleep(0.1) # Beispiel: Wartezeit von 0.1 Sekunden def df_update(self): from safe_to_excel import df return df.copy() def stop(self): self.running = False print("Data Updater Thread geschlossen") def stop(self): self.running = False print("Date Updater Thread geschlossen") async def main(): pass # non blocking program if __name__ == "__main__": asyncio.run(main())