Daten an ESP32 via BLE (bleack) kommen nicht an

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Nietzsche
User
Beiträge: 20
Registriert: Dienstag 2. Mai 2023, 13:15

Hallo,

ich möchte meine Sensorkonfiguration via BLE ändern, dazu habe ich folgenden Code in Python:

Code: Alles auswählen

import tkinter as tk
import tkinter.ttk as ttk
import bleak
import asyncio
from bleak import BleakClient

address = 'CC:50:E3:9C:15:02'
UUID3 = "beb5483e-36e1-4688-b7f5-ea07361b26a7"



async def handle_uuid3_notify(sender, data):
    value = int.from_bytes(data, byteorder='little')
    print(f"Neuer Wert empfangen: {value}")

async def send_data():
    # Extrahiere Eingabewerte
    led_brightness = int(e1.get())
    sample_average = int(e2.get())
    led_mode = int(e3.get())
    sample_rate = int(e4.get())
    pulse_width = int(e5.get())
    adc_range = int(e6.get())

    # Erstelle Datenpaket
    data_packet = bytearray([led_brightness, sample_average, led_mode, sample_rate, pulse_width, adc_range])

    # Sende Daten über BLE
    async with BleakClient(address) as client:
        await client.write_gatt_char(UUID3, data_packet)


senden = send_data()


async def read_data():
    async with BleakClient(address) as client:
        await client.start_notify(UUID3, handle_uuid3_notify)
        while True:
            await asyncio.sleep(1)




async def main():
    loop = asyncio.get_running_loop()
    loop.create_task(send_data())
    loop.create_task(read_data())
    await asyncio.sleep(0)

root = tk.Tk()
root.geometry('400x400')
root.title("ESP32 Einstellungen")

# Erstelle Label und Eingabefelder
tk.Label(root, text="ledBrightness").grid(row=0)
tk.Label(root, text="sampleAverage").grid(row=1)
tk.Label(root, text="ledMode").grid(row=2)
tk.Label(root, text="sampleRate").grid(row=3)
tk.Label(root, text="pulseWidth").grid(row=4)
tk.Label(root, text="adcRange").grid(row=5)

e1 = ttk.Entry(root)
e2 = ttk.Entry(root)
e3 = ttk.Entry(root)
e4 = ttk.Entry(root)
e5 = ttk.Entry(root)
e6 = ttk.Entry(root)

e1.grid(row=0, column=1, padx=3, pady=3)
e2.grid(row=1, column=1, padx=3, pady=3)
e3.grid(row=2, column=1, padx=3, pady=3)
e4.grid(row=3, column=1, padx=3, pady=3)
e5.grid(row=4, column=1, padx=3, pady=3)
e6.grid(row=5, column=1, padx=3, pady=3)


# Erstelle Button zum Verbinden mit dem ESP
#connect_button = ttk.Button(root, text="Mit ESP verbinden", command=connect_to_esp)


#connect_button.grid(row=6, column=0, columnspan=2, pady=10)
#command=lambda: asyncio.create_task(connect_to_esp())

async def main(address):
    async with BleakClient(address) as client:
        model_number = await client.read_gatt_char(UUID3)
        print("Verbunden")


# Erstelle Button zum Senden der Daten
send_button = ttk.Button(root, text="Senden", command=senden)
send_button.grid(row=7, column=0, columnspan=2, pady=5)



asyncio.run(main(address))

root.mainloop()
Leider kommt bei meinem ESP serial keine Bestätigung, dass die Sensordaten aktualisiert wurden. Kann das mal jemand bitte prüfen? Der ESP Code wäre hier:
https://pastebin.com/40Uf9ayK

Suche schon den ganzen Tag, komme aber nicht weiter.
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Tkinter uns asyncio muss man richtig integrieren. Mehrere Mains sind auch nicht sinnvoll.

Zur Integration kann man zb https://pypi.org/project/aiotkinter/ benutzen.

Ob der ESP Code tut, testest du mit einem reinen Test-Skript ohne GUI, nur mit bleak.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Nietzsche: Das Programm hat einen ganzen Haufen Probleme die zu Warnungen und Fehlermeldungen führen. Und es müsste doch auch auffallen, dass die GUI erst läuft, nachdem der Async-Teil abgearbeitet ist. *Dann* geht aber in der GUI-Hauptschleife kein sinnvoller Aufruf von ``async``-Funktionen mehr, weil *die* Schleife dann ja schon *nicht* mehr läuft.

Das ``senden = send_data()`` mach überhaupt gar keinen Sinn und `senden` ist auch nichts was aufrufbar ist und als `command` funktionieren würde.

`main` wird zweimal definiert, da bleibt dann effektiv die zweite Definition und die erste hat keinen Effekt.

`read_data()` wird nirgends verwendet. `send_data()` effektiv auch nicht, weil die Zeile in der `senden` definiert wird, keinen Sinn macht.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. Der Name soll dem Leser vermitteln was der Wert dahinter im Programm bedeutet, nicht zum rätseln zwingen.

Man nummeriert keine Namen. Dann will man sich entweder bessere Namen überlegen, oder gar keine Einzelnamen/-werte verwenden, sondern eine Datenstruktur. Oft eine Liste. So wahrscheinlich auch bei `e1` bis `e6`.

Die Fenstergrösse sollte man so nicht vorgeben. Das kann passen, muss aber nicht. Es kann auch sein, dass die angegebenen Pixel nicht ausreichen um den Fensterinhalt darzustellen und dann verschwinden Teile der Benutzeroberfläche und die GUI kann unbenutzbar werden. Die Fenstergrösse ergibt sich doch automatisch aus dem Inhalt des Fensters.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Nietzsche
User
Beiträge: 20
Registriert: Dienstag 2. Mai 2023, 13:15

Vielen Dank für die ausführliche Kritik! Ich habe mein Skript nochmal überarbeitet und konnte dann die Daten an den ESP erfolgreich übertragen. Jetzt habe ich mir eine GUI dazu gemacht und möchte meine async Funktion über einen Button öffnen, leider klappt das nicht nicht so ganz, der ganze Code findet sich hier: https://pastebin.com/AVnzL1cB

Was mache ich falsch?

Code: Alles auswählen

def update_variables(self):
        global Variable1, Variable2, Variable3, Variable4, Variable5, Variable6

        Variable1 = int(self.textEdit.toPlainText())
        Variable2 = self.textEdit_2.toPlainText()
        Variable3 = self.comboBox_3.currentText()
        Variable4 = self.textEdit_4.toPlainText()
        Variable5 = self.comboBox.currentText()
        Variable6 = self.comboBox_2.currentText()

        print("Variablen aktualisiert:")

        on_pushButton_click()

   self.pushButton.clicked.connect(self.update_variables)


def on_pushButton_click():
    print("Variablen:", Variable1,";", Variable2,";", Variable3,";", Variable4,";", Variable5,";", Variable6)
    asyncio.create_task(send_data())


    await send_data(1)

    try:

        writer = lambda msg: print(msg)
        writer("sende Daten...")

        async with bleak.BleakClient(mac_address) as client:
            # String erstellen
            str_parameters = f"{Variable1},{Variable2},{Variable3},{Variable4},{Variable5},{Variable6}"

            # Byte-Array erstellen
            byte_array = str_parameters.encode('ascii')

            print("Sende Werte")
            # Array senden
            await client.write_gatt_char(UUID3, byte_array)

            # Receive data from ESP32 via BLE
            received = False  # Variable to indicate whether data has been received

            while not received:
                data = await client.read_gatt_char(UUID3)
                if data:
                    value = data.decode('utf-8')
                    print(f"{value}")
                    received = True

    except Exception as e:
        print("Nicht verbunden")
        print(e)
Die wichtigen Codezeilen habe hier hier extra gepostet, der Rest steht in der Pastebin. Würde mich sehr über erneute Hilfe freuen! Die Parameter werden übrigens korrekt aktualisiert und nach dem Drücken des buttons in der Konsole geprintet, nur wird meine async Funktion scheinbar nicht aufgerufen, da ich weder Nicht verbunden bekomme noch Daten an den ESP geschickt werden.

LG
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Nietzsche: Vergiss bitte ``global`` sofort wieder. Das hat in einem sauberen Programm nichts zu suchen und wenn man Klassen hat, gibt es auch keine Ausrede mehr das überhaupt zu verwenden. Im vorliegenden Code macht das auch gar keinen Sinn die Werte von Eingabeelementen in globale Variablen zu verfrachten um dann eine Funktion ohne Argumente aufzurufen wo dann auf die globalen Variablen zugegriffen wird. Da hätte man einfach die Werte beim Aufruf übergeben sollen.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Man nummeriert keine Namen. Dann will man sich entweder bessere Namen überlegen, oder gar keine Einzelnamen/-werte verwenden, sondern eine Datenstruktur. Oft eine Liste. Bei `Variable1` bis `Variable6` sollten es aber wohl wirklich *sinnvolle* Namen sein.

Der GUI-Code sieht aus als wäre er vom Designer generiert. Da war ja mal ein Kommentar am Anfang der eindringlich davor gewarnt hat den zu verändern. Diese generierte Datei fasst man nicht an. Die importiert man in einem anderen Modul und verwendet das was da generiert wurde.

Am GUI-Code sieht man, dass da kein Layout verwendet wurde, sondern die Elemente an absoluten Pixelpositionen platziert wurden und die Grössen in Pixeln hart vorgegeben sind. Das funktioniert so nicht, beziehungsweise nur auf dem System wo das entworfen wurde, oder welchen die sehr ähnliche Bildschirmgrösse, -auflösung, und -einstellungen haben. Das ist bei dem heutigen Zoo an unterschiedlicher Displayhardware nicht machbar. Das kann auf anderen Systemen komisch aussehen, bis unbenutzbar sein, wenn die Elemente/deren Inhalte nicht in den verfügbaren Platz passen. Man generiert eigentlich auch keine Quelltexte mehr, sondern lädt die ``*.ui``-Datei mit dem `PyQt6.uic`-Modul zur Laufzeit.

Die Ausnahmebehandlung macht so keinen Sinn. Man bekommt einfach nur *weniger* Informationen um einen Fehler zu finden als wenn man das ``try``/``except`` dort einfach weg lässt.

``writer = lambda msg: print(msg)`` wäre einfacher ``writer = print``. Und dann könnte man fragen warum Du `print()` unbedingt unter dem Namen `writer` ansprechen willst.

Ich denke der Hauptfehler ist als Anfänger nicht nur eine GUI schreiben zu wollen, sondern das auch noch mit nebenläufiger Programmierung, und *das* dann auch noch mit `asyncio`. Was schwierigeres/komplexeres kann man sich ja fast gar nicht aussuchen. Die einzelnen Komponenten die man dafür lernen muss sind Funktionen (also echte, ohne ``global``/globalen Zustand), Klassen, nebenläufige Programmierung mit ``async`` & Co, GUI-Programmierung (ereignisorientiert), dann GUI + Threads, um letztlich GUI-Hauptschleife und ``async``-Hauptschleife irgendwie in einem Programm unterbringen zu können. Jedes dieser Themen für sich braucht Zeit. Wenn man sich das alles auf einmal antut, kann man eigentlich nur verlieren.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Warum plötzlich alles in Qt? Auch hier gilt: einfach irgendwie asyncio mit einem GUI Framework zusammenkloppen geht halt nicht. Wieses gehen kann, siehe zb hier: https://doc.qt.io/qtforpython-6/example ... nimal.html
Benutzeravatar
DeaD_EyE
User
Beiträge: 1017
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Code: Alles auswählen

def on_pushButton_click():
    print("Variablen:", Variable1,";", Variable2,";", Variable3,";", Variable4,";", Variable5,";", Variable6)
    asyncio.create_task(send_data())


    await send_data(1)
Das sollte einen SyntaxError auslösen, da await in einer normalen Funktion verwendet wird.

Mit asyncio und GUIs haben selbst Profis so ihre Probleme. Das selbst zu implementieren geht, wenn man asyncio und das GUI-Framework in- und auswendig kennt.

Hier hat jemand ein Beispiel mit tkinter gemacht: https://www.loekvandenouweland.com/cont ... inter.html
Du solltest den Code nur verwenden, wenn du ihn verstehst.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@DeaD_Eye: mal wieder so ein typisches Tk-Beispiel. Es wird mit Window ein tk.Tk-Objekt erzeugt, aber nicht einmal richtig initialisiert. Statt dessen wird mit root ein zweites Tk-Objekt erzeugt, wovon es aber eigentlich nur eins geben dürfte. Die ganzen Widgets werden implizit für eines der beiden Tk-Objekte erzeugt, statt explizit einen Parent anzugeben. Und natürlich wird update verwendet, statt umgekehrt den async-Loop per after zu treiben.

Code: Alles auswählen

import tkinter as tk
from tkinter import ttk
import asyncio

class Window(tk.Tk):
    def __init__(self, loop):
        super().__init__()
        self.loop = loop
        self.animation = "░▒▒▒▒▒"
        self.count = 0
        self.label = tk.Label(self, text="")
        self.label.grid(row=0, columnspan=2, padx=(8, 8), pady=(16, 0))
        self.progressbar = ttk.Progressbar(self, length=280)
        self.progressbar.grid(row=1, columnspan=2, padx=(8, 8), pady=(16, 0))
        button_block = tk.Button(self, text="Calculate Sync", width=10, command=self.calculate_sync)
        button_block.grid(row=2, column=0, sticky=tk.W, padx=8, pady=8)
        button_non_block = tk.Button(self, text="Calculate Async", width=10, command=lambda: self.loop.create_task(self.calculate_async()))
        button_non_block.grid(row=2, column=1, sticky=tk.W, padx=8, pady=8)
        self.event_loop()

    def event_loop(self):
        if self.count % 10 == 0:
            self.label["text"] = self.animation
            self.animation = self.animation[1:] + self.animation[0]
        self.count += 1
        self.loop.stop()
        self.loop.run_forever()
        self.after(10, self.event_loop)

    def calculate_sync(self):
        max = 3000000
        for i in range(1, max):
            self.progressbar["value"] = i / max * 100

    async def calculate_async(self):
        max = 3000000
        for i in range(1, max):
            self.progressbar["value"] = i / max * 100
            if i % 1000 == 0:
                await asyncio.sleep(0)


def main():
    loop = asyncio.get_event_loop()
    window = Window(loop)
    window.mainloop()

if __name__ == "__main__":
    main()
Benutzeravatar
Dennis89
User
Beiträge: 1153
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ich hätte mal eine Zwischenfrage. Falls die Antwort Grundkenntnisse von 'asyncio' voraussetzt, dann braucht ihr nicht tiefer darauf eingehen, die habe ich noch nicht.
Wieso wird in 'event_loop' die Geschwindigkeit der Animation mit 'counter' bestimmt, anstatt die Zeit in 'after' zum Beispiel auf 100 zu erhöhen?
Ich denke, dass das irgendwas mit dem 'loop.stop()' und 'loop.run_forever()' zu tun hat, da ich das nicht kenne, wollte ich einfach mal nachfragen.

Danke und gute Nacht
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das kommt ein bisschen auf das Ziel an. Das ist ja keine butterweiche Animation von 100ten Pixeln. Da will man verflossene Zeit messen. Aber hier gehts ja einfach nur um Pi mal Daumen Fortschritt.
Benutzeravatar
Dennis89
User
Beiträge: 1153
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Morgen,

achsoo, okay vielen Dank.


Grüße Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
DeaD_EyE
User
Beiträge: 1017
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Sirius3 hat geschrieben: Montag 15. Mai 2023, 22:30 @DeaD_Eye: mal wieder so ein typisches Tk-Beispiel. Es wird mit Window ein tk.Tk-Objekt erzeugt, aber nicht einmal richtig initialisiert. Statt dessen wird mit root ein zweites Tk-Objekt erzeugt, wovon es aber eigentlich nur eins geben dürfte. Die ganzen Widgets werden implizit für eines der beiden Tk-Objekte erzeugt, statt explizit einen Parent anzugeben. Und natürlich wird update verwendet, statt umgekehrt den async-Loop per after zu treiben.
Ich würde weiterhin window.update() verwenden, da für mich primär die Eventloop alles vorgibt und nicht tkinter. Die Eventloop jedes Mal zu starten und zu stoppen, gefällt mir einfach nicht.

Das Beispiel habe ich mir gar nicht so genau angesehen. Da die Klasse von tkinter.Tk geerbt wird, ist die Instanz der Klasse der master. Noch mal in der Klasse Tk() zu instanziieren ist nutzlos.

Die Probleme gehen aber weiter. Versuch mal das Programm sauber zu beenden, wenn es komplexer wird. Viel Spaß.....
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
DeaD_EyE
User
Beiträge: 1017
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Nachtrag: Die Idee ein GUI-Framework asynchron zu nutzen, kommt sicherlich von Micropython. Mir sind keine GUI-Frameworks für Micropython bekannt, die synchron arbeiten. D.h. man muss sich zwangsweise mit asyncio beschäftigen oder man kann keine GUI auf dem Microcontroller in Python entwickeln. Da aber Threads und Prozesse bei CPython zur Verfügung stehen, ist das nicht ganz so schlimm. Neuere Toolkits nutzen bereits asyncio wie z.B. Textual.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Nietzsche
User
Beiträge: 20
Registriert: Dienstag 2. Mai 2023, 13:15

Was wäre denn mit https://github.com/CabbageDevelopment/q ... CVqQw458lg qasync?

Die Beispiele sind für pyqt 5 aber vermutlich geht das auch mit 6 ? Was meint ihr?
Nietzsche
User
Beiträge: 20
Registriert: Dienstag 2. Mai 2023, 13:15

Hallo!

also ich habe nun weiter einige Kritiken bearbeitet, zumindest hoffe ich das. Zunächst hier mal mein Programm das soweit funktioniert, nachdem ich es starte werden mir die Parameter an meinen ESP gesendet, die Variablen habe ich noch nicht umbenannt, aber das werde ich dann im Feinschliff noch machen: https://pastebin.com/4QQMbaXJ

Meine GUI habe im neu designet und zwar so, dass es responsiv ist, hierzu einmal der Python Code:

Code: Alles auswählen

# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'MAX_BLE_Kalibrierer_2QkaXmB.ui'
##
## Created by: Qt User Interface Compiler version 6.4.3
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
    QCursor, QFont, QFontDatabase, QGradient,
    QIcon, QImage, QKeySequence, QLinearGradient,
    QPainter, QPalette, QPixmap, QRadialGradient,
    QTransform)
from PySide6.QtWidgets import (QApplication, QComboBox, QFormLayout, QLabel,
    QLineEdit, QMainWindow, QMenu, QMenuBar,
    QPushButton, QSizePolicy, QSpacerItem, QStatusBar,
    QWidget)
import ble_rc

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(324, 727)
        MainWindow.setMinimumSize(QSize(0, 0))
        MainWindow.setSizeIncrement(QSize(0, 0))
        MainWindow.setBaseSize(QSize(0, 1))
        MainWindow.setLayoutDirection(Qt.LeftToRight)
        MainWindow.setDockNestingEnabled(False)
        self.exit_button = QAction(MainWindow)
        self.exit_button.setObjectName(u"exit_button")
        self.actionMAC_ndern = QAction(MainWindow)
        self.actionMAC_ndern.setObjectName(u"actionMAC_ndern")
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.formLayout = QFormLayout(self.centralwidget)
        self.formLayout.setObjectName(u"formLayout")
        self.verticalSpacer_4 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)

        self.formLayout.setItem(0, QFormLayout.LabelRole, self.verticalSpacer_4)

        self.label = QLabel(self.centralwidget)
        self.label.setObjectName(u"label")
        font = QFont()
        font.setFamilies([u"Segoe UI Variable"])
        font.setPointSize(16)
        font.setBold(False)
        font.setItalic(False)
        font.setUnderline(False)
        self.label.setFont(font)
        self.label.setAlignment(Qt.AlignCenter)

        self.formLayout.setWidget(1, QFormLayout.SpanningRole, self.label)

        self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)

        self.formLayout.setItem(3, QFormLayout.LabelRole, self.verticalSpacer)

        self.label_led_helligkeit = QLabel(self.centralwidget)
        self.label_led_helligkeit.setObjectName(u"label_led_helligkeit")
        font1 = QFont()
        font1.setBold(False)
        font1.setUnderline(True)
        self.label_led_helligkeit.setFont(font1)

        self.formLayout.setWidget(4, QFormLayout.LabelRole, self.label_led_helligkeit)

        self.Feld_Led_Helligkeit = QLineEdit(self.centralwidget)
        self.Feld_Led_Helligkeit.setObjectName(u"Feld_Led_Helligkeit")
        font2 = QFont()
        font2.setFamilies([u"Segoe UI Light"])
        font2.setPointSize(12)
        self.Feld_Led_Helligkeit.setFont(font2)

        self.formLayout.setWidget(6, QFormLayout.SpanningRole, self.Feld_Led_Helligkeit)

        self.label_default_led_helligkeit = QLabel(self.centralwidget)
        self.label_default_led_helligkeit.setObjectName(u"label_default_led_helligkeit")
        font3 = QFont()
        font3.setPointSize(9)
        font3.setItalic(True)
        self.label_default_led_helligkeit.setFont(font3)
        self.label_default_led_helligkeit.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)

        self.formLayout.setWidget(7, QFormLayout.SpanningRole, self.label_default_led_helligkeit)

        self.label_probemenge = QLabel(self.centralwidget)
        self.label_probemenge.setObjectName(u"label_probemenge")
        self.label_probemenge.setFont(font1)

        self.formLayout.setWidget(8, QFormLayout.SpanningRole, self.label_probemenge)

        self.Feld_Probemenge = QLineEdit(self.centralwidget)
        self.Feld_Probemenge.setObjectName(u"Feld_Probemenge")
        self.Feld_Probemenge.setFont(font2)

        self.formLayout.setWidget(9, QFormLayout.SpanningRole, self.Feld_Probemenge)

        self.label_default_probemenge = QLabel(self.centralwidget)
        self.label_default_probemenge.setObjectName(u"label_default_probemenge")
        font4 = QFont()
        font4.setItalic(True)
        self.label_default_probemenge.setFont(font4)
        self.label_default_probemenge.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)

        self.formLayout.setWidget(10, QFormLayout.SpanningRole, self.label_default_probemenge)

        self.label_modus = QLabel(self.centralwidget)
        self.label_modus.setObjectName(u"label_modus")
        self.label_modus.setFont(font1)

        self.formLayout.setWidget(12, QFormLayout.LabelRole, self.label_modus)

        self.Box_Led_Mode = QComboBox(self.centralwidget)
        self.Box_Led_Mode.addItem("")
        self.Box_Led_Mode.addItem("")
        self.Box_Led_Mode.addItem("")
        self.Box_Led_Mode.setObjectName(u"Box_Led_Mode")
        self.Box_Led_Mode.setFont(font2)

        self.formLayout.setWidget(13, QFormLayout.SpanningRole, self.Box_Led_Mode)

        self.label_default_led_modus = QLabel(self.centralwidget)
        self.label_default_led_modus.setObjectName(u"label_default_led_modus")
        self.label_default_led_modus.setFont(font4)
        self.label_default_led_modus.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)

        self.formLayout.setWidget(15, QFormLayout.SpanningRole, self.label_default_led_modus)

        self.label_abtastrate = QLabel(self.centralwidget)
        self.label_abtastrate.setObjectName(u"label_abtastrate")
        font5 = QFont()
        font5.setBold(False)
        font5.setItalic(False)
        font5.setUnderline(True)
        self.label_abtastrate.setFont(font5)

        self.formLayout.setWidget(17, QFormLayout.LabelRole, self.label_abtastrate)

        self.Feld_Abtastrate = QLineEdit(self.centralwidget)
        self.Feld_Abtastrate.setObjectName(u"Feld_Abtastrate")
        self.Feld_Abtastrate.setFont(font2)

        self.formLayout.setWidget(18, QFormLayout.SpanningRole, self.Feld_Abtastrate)

        self.label_default_abtastrate = QLabel(self.centralwidget)
        self.label_default_abtastrate.setObjectName(u"label_default_abtastrate")
        self.label_default_abtastrate.setFont(font4)
        self.label_default_abtastrate.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)

        self.formLayout.setWidget(19, QFormLayout.SpanningRole, self.label_default_abtastrate)

        self.label_pulsweite = QLabel(self.centralwidget)
        self.label_pulsweite.setObjectName(u"label_pulsweite")
        self.label_pulsweite.setFont(font1)

        self.formLayout.setWidget(21, QFormLayout.LabelRole, self.label_pulsweite)

        self.Box_Pulsweite = QComboBox(self.centralwidget)
        self.Box_Pulsweite.addItem("")
        self.Box_Pulsweite.addItem("")
        self.Box_Pulsweite.addItem("")
        self.Box_Pulsweite.addItem("")
        self.Box_Pulsweite.setObjectName(u"Box_Pulsweite")
        self.Box_Pulsweite.setFont(font2)

        self.formLayout.setWidget(22, QFormLayout.SpanningRole, self.Box_Pulsweite)

        self.label_detault_pulsweite = QLabel(self.centralwidget)
        self.label_detault_pulsweite.setObjectName(u"label_detault_pulsweite")
        self.label_detault_pulsweite.setFont(font4)
        self.label_detault_pulsweite.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)

        self.formLayout.setWidget(24, QFormLayout.SpanningRole, self.label_detault_pulsweite)

        self.label_adc_bereich = QLabel(self.centralwidget)
        self.label_adc_bereich.setObjectName(u"label_adc_bereich")
        self.label_adc_bereich.setFont(font1)

        self.formLayout.setWidget(26, QFormLayout.LabelRole, self.label_adc_bereich)

        self.Box_ADC_Bereich = QComboBox(self.centralwidget)
        self.Box_ADC_Bereich.addItem("")
        self.Box_ADC_Bereich.addItem("")
        self.Box_ADC_Bereich.addItem("")
        self.Box_ADC_Bereich.addItem("")
        self.Box_ADC_Bereich.setObjectName(u"Box_ADC_Bereich")
        self.Box_ADC_Bereich.setFont(font2)
        self.Box_ADC_Bereich.setInsertPolicy(QComboBox.InsertAtCurrent)
        self.Box_ADC_Bereich.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)

        self.formLayout.setWidget(27, QFormLayout.SpanningRole, self.Box_ADC_Bereich)

        self.label_default_adc_bereich = QLabel(self.centralwidget)
        self.label_default_adc_bereich.setObjectName(u"label_default_adc_bereich")
        self.label_default_adc_bereich.setFont(font4)
        self.label_default_adc_bereich.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)

        self.formLayout.setWidget(29, QFormLayout.SpanningRole, self.label_default_adc_bereich)

        self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)

        self.formLayout.setItem(31, QFormLayout.LabelRole, self.verticalSpacer_2)

        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")
        font6 = QFont()
        font6.setPointSize(14)
        self.pushButton.setFont(font6)

        self.formLayout.setWidget(32, QFormLayout.SpanningRole, self.pushButton)

        self.label_2 = QLabel(self.centralwidget)
        self.label_2.setObjectName(u"label_2")
        self.label_2.setAlignment(Qt.AlignCenter)

        self.formLayout.setWidget(34, QFormLayout.SpanningRole, self.label_2)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 324, 22))
        self.menuDatei = QMenu(self.menubar)
        self.menuDatei.setObjectName(u"menuDatei")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.menubar.addAction(self.menuDatei.menuAction())
        self.menuDatei.addAction(self.exit_button)

        self.retranslateUi(MainWindow)
        self.exit_button.triggered.connect(MainWindow.close)

        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.exit_button.setText(QCoreApplication.translate("MainWindow", u"Quit", None))
        self.actionMAC_ndern.setText(QCoreApplication.translate("MainWindow", u"MAC \u00e4ndern", None))
        self.label.setText(QCoreApplication.translate("MainWindow", u"MAXIM 30102  BLE UPDATE ", None))
        self.label_led_helligkeit.setText(QCoreApplication.translate("MainWindow", u"Led Helligkeit", None))
        self.label_default_led_helligkeit.setText(QCoreApplication.translate("MainWindow", u"0 - 50 mA", None))
        self.label_probemenge.setText(QCoreApplication.translate("MainWindow", u"Probenmenge ", None))
        self.label_default_probemenge.setText(QCoreApplication.translate("MainWindow", u"SAMPLEAVG_ (1-32)", None))
        self.label_modus.setText(QCoreApplication.translate("MainWindow", u"Led Modus", None))
        self.Box_Led_Mode.setItemText(0, QCoreApplication.translate("MainWindow", u"MODE_MULTILED", None))
        self.Box_Led_Mode.setItemText(1, QCoreApplication.translate("MainWindow", u"MODE_IR", None))
        self.Box_Led_Mode.setItemText(2, QCoreApplication.translate("MainWindow", u"MODE_RED", None))

        self.label_default_led_modus.setText(QCoreApplication.translate("MainWindow", u"Default: MODE_ MULTILED", None))
        self.label_abtastrate.setText(QCoreApplication.translate("MainWindow", u"Abtastrate", None))
        self.label_default_abtastrate.setText(QCoreApplication.translate("MainWindow", u"SAMPLERATE_(50 - 400 Hz)", None))
        self.label_pulsweite.setText(QCoreApplication.translate("MainWindow", u"Pulsweite", None))
        self.Box_Pulsweite.setItemText(0, QCoreApplication.translate("MainWindow", u"PULSEWIDTH_69", None))
        self.Box_Pulsweite.setItemText(1, QCoreApplication.translate("MainWindow", u"PULSEWIDTH_118", None))
        self.Box_Pulsweite.setItemText(2, QCoreApplication.translate("MainWindow", u"PULSEWIDTH_215", None))
        self.Box_Pulsweite.setItemText(3, QCoreApplication.translate("MainWindow", u"PULSEWIDTH_411", None))

        self.label_detault_pulsweite.setText(QCoreApplication.translate("MainWindow", u"Default: PULSEWIDTH_411", None))
        self.label_adc_bereich.setText(QCoreApplication.translate("MainWindow", u"ADC Bereich", None))
        self.Box_ADC_Bereich.setItemText(0, QCoreApplication.translate("MainWindow", u"ADCRANGE_2048", None))
        self.Box_ADC_Bereich.setItemText(1, QCoreApplication.translate("MainWindow", u"ADCRANGE_4096", None))
        self.Box_ADC_Bereich.setItemText(2, QCoreApplication.translate("MainWindow", u"ADCRANGE_8192", None))
        self.Box_ADC_Bereich.setItemText(3, QCoreApplication.translate("MainWindow", u"ADCRANGE_16384", None))

        self.label_default_adc_bereich.setText(QCoreApplication.translate("MainWindow", u"Default: ADCRANGE_16384", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"senden", None))
        self.label_2.setText("")
        self.menuDatei.setTitle(QCoreApplication.translate("MainWindow", u"Datei", None))
    # retranslateUi

Das einbinden muss ich noch eruieren, da ich zuletzt beim aligne etwas ändern musste. Kopiere ich den Code so in mein File, dann bekomme ich einen Error. Aber nun kommen wir zu meinem aktuellen Stand der Dinge: Ich möchte jetzt meine GUI mit meinem Programm so verbinden, dass ich die Eingabefenster und Boxen mit meinen Variablen verbinde und meine Funktion über meinen Button aufrufe. Kann mir da jemand weiterhelfen?

LG
Nietzsche
User
Beiträge: 20
Registriert: Dienstag 2. Mai 2023, 13:15

Es gibt einmal wieder ein Update von mir. :) Das mit den .ui Dateien habe ich nun geändert, so dass ich die .ui einbinde und nicht mehr den Code kopiere, danke für den Hinweis! So macht der qt Designer mehr Spaß! Meine Funktion konnte ich erfolgreich ausführen und eine kleine GUI dazu ebenfalls basteln. Nun will ich aber meine Funktion in mein neues Programm einpflegen (mit der eingebundenen .ui bzw 2) und ich bekomme einen Error:

Einstellungen Button gedrückt
QThread: Destroyed while thread is still running
Drücken Sie eine beliebige Taste . . .


Hier der Code: https://pastebin.com/JbDJrXe1

Vielleicht kann mir nochmal wer weiterhelfen. :)
Antworten