Zugriff auf QLCDNumber von Modul

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
stresch89
User
Beiträge: 8
Registriert: Montag 31. Juli 2023, 19:43

Hallo,

ich versuche von einem Modul ('test.py') das QLCDNumber-Widget in der GUI(widget.py) zu "verändern", also mit display(x) den Wert zu ändern. Dies klappt allerdings nicht.
Egal was ich bis jetzt versucht habe bekomme ich immer folgenden Fehler:
widget.widget.lcdSPEED.display(33)
AttributeError: module 'widget' has no attribute 'widget'. Did you mean: 'Widget'?
Wie kann ich vom Modul "test.py" auf das QLCDNumber vom Widget in "widget.py" zugreifen und den Wert ändern?

Danke im Voraus

Gruß Silas
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Mit Modulen organisiert man nur die Definition von Klassen und Funktionen. Den konkreten Instanzen ist es egal, aus welchem Modul der Code dazu ursprünglich mal herkam.
Wenn Du also auf eine Instanz in einer Methode zugreifen willst, mußt Du sie als Argument übergeben.
stresch89
User
Beiträge: 8
Registriert: Montag 31. Juli 2023, 19:43

Kannst du mir ein Beispiel geben?
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein, weil dazu der Code fehlt. Der Hinweis bezog sich nur auf ein fundamentales Missverständnis, wie Klassen Funktionieren. Die sind blaupausen. Wenn du die Tür deines Autos öffnen willst, musst du schon dein Auto selbst vor dir haben. Nicht den Plan, nach dem es und alle seine Freunde gebaut wurden. Nur weiß keiner, wo du dein Auto abgestellt hast - weil, kein Code.
stresch89
User
Beiträge: 8
Registriert: Montag 31. Juli 2023, 19:43

hier der Code von "widget.py"

Code: Alles auswählen

# This Python file uses the following encoding: utf-8
import os
from pathlib import Path
import sys
import setup
from threading import Thread

from PySide2.QtWidgets import QApplication, QWidget, QLCDNumber, QPushButton
from PySide2.QtCore import QFile
from PySide2.QtUiTools import QUiLoader
import rtdata
vSpeed = 0.0
vRPM = 0.0


class Widget(QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        self.load_ui()
        self.lcdSPEED = self.findChild(QLCDNumber, "lcdSPEED")
        self.lcdRPM = self.findChild(QLCDNumber, "lcdRPM")
        self.btnStart = self.findChild(QPushButton, "btnStart")


        self.btnStart.clicked.connect(self.clickedBtnStart)

    def load_ui(self):
        loader = QUiLoader()
        path = os.fspath(Path(__file__).resolve().parent / "form.ui")
        ui_file = QFile(path)
        ui_file.open(QFile.ReadOnly)
        loader.load(ui_file, self)
        ui_file.close()

    def clickedBtnStart(self):
        print("push")

        self.lcdSPEED.display(12)

        t = Thread(target=rtdata.test)
        t.start()
        #self.lcdSPEED.display(vSpeed)
        #self.lcdRPM.display(vRPM)

if __name__ == "__main__":
    app = QApplication([])
    widget = Widget()
    widget.show()

    sys.exit(app.exec_())

hier der Code vom Modul "rtdata.py":

Code: Alles auswählen

mport obd
from obd import OBDStatus
import time
import setup
import widget
from setup import rtTimer
from PySide2.QtWidgets import QLCDNumber

data1 = ""
data2 = ""
data3 = ""



connection = obd.Async(setup.comAdapter, setup.comBaud, fast=setup.comFast
                            , timeout=setup.comTimeout)
def test():
    print("push2")
    we = widget.Widget()
    lcd = we.findChild(QLCDNumber, "lcdRPM")
    lcd.display(33)
    lcd.update()
def rt2():

    w = widget.Widget()
    connection.watch(obd.commands.RPM)
    connection.watch(obd.commands.SPEED)

    connection.start() # start the async update loop
    time.sleep(1)
    rtTimer= 101

    while rtTimer > 100:
        r=connection.query(obd.commands.RPM)
        r2=connection.query(obd.commands.SPEED)
        if r.is_null():
            connection.stop()
            return
        else:
            rS = str(r2.value.magnitude)
            rD = str(r.value.magnitude)
            r3=  rS + "km/h  bei  " + rD + "U/min"
            rtTimer = float(r.value.magnitude)
            w.self.lcdRPM = r.value.magnitude
            w.self.lcdSPEED = r2.value.magnitude
            #print(r3, end='\r')
        time.sleep(0.5)
    connection.stop()
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das geht so alles nicht. Du darfst keine GUI-Objekte außerhalb des main Threads erzeugen, und anfassen. Für zyklische Aufgaben benutzt man in Qt (und allen GUIs) Timer. Schmeiß alles aus rdata raus was GUI ist, und Bau da eine Klasse, welche die connection aufbaut und auf Nachfrage die Werte liefert. Und die instantiierst du aus widget.py und fragst im Timer(!) die Werte ab.
stresch89
User
Beiträge: 8
Registriert: Montag 31. Juli 2023, 19:43

Hi,

erstmal danke für die Antwort. Ja ich verstehe den "Aufbau" ansich. Das habe ich anfangs auch so probiert, nur ist mein Problem wenn ich mir eine Klasse für Connection und das liefern der Daten baue und dann im main die Funktion oder Klasse aufrufe bleibt das Window schwarz, klar weil die Funktion oder Klasse die Werte ausgibt. Deshalb habe ich das so probiert...

Dann versuche ich es nochmal.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ohne Code kann man dazu nix sagen. Aber auch nur ein while loop, und es geht eben nicht. Punkt.GUI Programmierung hat da eben Tücken.
Antworten