Checkbox als Anzeige nutzen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Bulli
User
Beiträge: 10
Registriert: Mittwoch 22. Februar 2017, 12:45

Hallo,
Ich versuche gerade eine Checkbox als anzeige zu benutzen.
das heist ich bekomme ein Signal über ein I/O Eingang,
der wird über einen Thread(pysignal(bool)) an das Hauptfenster gesendet.
bekomme es aber nicht hin das er ohne das ich eine Aktion machen muss, als
checkbox gecheckt angezeigt wird. Also dynamisch angezeigt wird.
gibts da irgendwie eine Möglichkeit so einen Eingang dynamisch auf einer
Checkbox anzuzeigen?
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ohne Code schwer zu sagen, ich behaupte mal du hast das threading vergurkt und benutzt keine queued connections zwischen Signal und Slot.
Bulli
User
Beiträge: 10
Registriert: Mittwoch 22. Februar 2017, 12:45

hab da mal ein bischen Code von meinen Tests.
Wie würdet ihr vorgehen?

Code: Alles auswählen

import sys
import os
from testit1 import *
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
from PyQt5.QtCore import QThread, pyqtSignal, QObject


class Test(QThread):
    stateImput1 = pyqtSignal(bool)

    def __init__(self):
        super().__init__()

    def run(self):
        print("Thread ist gestartet")
        while readdigital(4):
            if readdigital(1):
                self.stateImput1.emit(True)
            else:
                self.stateImput1.emit(False)
            time.sleep(1)
        print("Thread ende")

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.thread = Test()
        self.state = False
        homepath = os.path.abspath(os.path.dirname(sys.argv[0]))
        ablaufprogrammUI = os.path.join(homepath, "PyQt5test.ui")
        ui = uic.loadUi(ablaufprogrammUI, self)

        self.checkbox_out1 = ui.checkBox_out1
        self.checkbox_out2 = ui.checkBox_out2
        self.checkbox_out3 = ui.checkBox_out3
        self.checkbox_in1  = ui.checkBox_in1
        self.checkbox_in2  = ui.checkBox_in2
        self.checkbox_in3  = ui.checkBox_in3
        self.checkbox_out1.toggled.connect(self.checkbox_toggle)
        self.checkbox_out2.toggled.connect(self.checkbox_toggle)
        self.checkbox_out3.toggled.connect(self.checkbox_toggle)
        self.thread.stateImput1.connect(self.threadAbfragen)
        self.checkbox_in1.checkState()
        self.checkbox_in3.toggled.connect(self.threadStarten)

    def slot_Method(self):
        print("test")

    def threadStarten(self):
        self.thread.start()

    def threadAbfragen(self, state):
        print(state)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist der klassisch falsche Ansatz. Ich habe hier mal einen richtigen gezeigt: viewtopic.php?f=24&t=44250&start=15#p335559

Dabei ist darauf zu achten, das man den Worker *erst* in den Hintegrundthread verschiebt, und DANN signal/slot connections macht.
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

Durch loadUi bindest Du Dir schon alle Widgets and self, das brauchst Du nicht nochmal händisch zu machen. Die Zuweisung an ui ist auch unsinnig, entweder self oder ui.
Ein __init__ das nichts macht außer die Eltern-__init__ aufzurufen ist überflüssig.
Keine Ahnung, was aus testit1 (ein äußerst schlechter Name für ein Modul) importiert wird, daher keine *-Importe!
Soll `stateImput1` wirklich mit m geschrieben sei? Was soll die 1?
Wenn sich ein if-Block und ein else-Block nur durch einen Boolean-Wert unterscheiden, braucht es kein if.

Code: Alles auswählen

import sys
import os
from testit1 import readdigital
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
from PyQt5.QtCore import QThread, pyqtSignal, QObject

ABLAUF_PROGRAMM_UI = os.path.join(os.path.dirname(__file__), "PyQt5test.ui")


class Test(QThread):
    stateImput1 = pyqtSignal(bool)

    def run(self):
        print("Thread ist gestartet")
        while readdigital(4):
            self.stateImput1.emit(bool(readdigital(1)))
            time.sleep(1)
        print("Thread ende")

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.thread = Test()
        uic.loadUi(ABLAUF_PROGRAMM_UI, self)
        self.checkBox_out1.toggled.connect(self.checkbox_toggle)
        self.checkBox_out2.toggled.connect(self.checkbox_toggle)
        self.checkBox_out3.toggled.connect(self.checkbox_toggle)
        self.thread.stateImput1.connect(self.threadAbfragen)
        self.checkBox_in1.checkState()
        self.checkBox_in3.toggled.connect(self.threadStarten)

    def slot_Method(self):
        print("test")

    def threadStarten(self):
        self.thread.start()

    def threadAbfragen(self, state):
        print(state)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Sirius3: aufgeraeumt ist nicht fundamental besser. Die Verbindungen werden alle im main-Thread gemacht, und wenn der dann emittet, kommen sie nicht in die richtige Queue.
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: ich wollte gar nichts besser machen.
Bulli
User
Beiträge: 10
Registriert: Mittwoch 22. Februar 2017, 12:45

Danke erstmal für eure Infos.
Werde das erstmal versuchen zu verstehen mit dem Thread in den Hintergrund schieben.
Das Modul "testit"(ich weis ist ein bescheidener Name) ist nur eine Anbindung zu einer in C geschriebenen USB-Schnittstelle (War nur eben mal schnell angelegt, sorry! )
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sirius3 hat geschrieben: Freitag 27. März 2020, 12:47 @__deets__: ich wollte gar nichts besser machen.
Das glaube ich dir. Ob der TE das auch bemerkt war da eher meine Sorge :)
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bulli hat geschrieben: Freitag 27. März 2020, 12:56 Werde das erstmal versuchen zu verstehen mit dem Thread in den Hintergrund schieben.
Das ist letztlich nur abgeleitet aus den offiziellen Empfehlungen von Qt selbst, wenn du dir die durchliest, kannst du das ggf. besser nachvollziehen.
Bulli
User
Beiträge: 10
Registriert: Mittwoch 22. Februar 2017, 12:45

Moin, Also wenn ich das richtig verstanden habe, Erzeuge ich im Mainloop einen Thread der die auserhalb liegende Funktion/Methode ausführt der über Singale mit dem Mainloop kommuniziert. Ist das richtig?
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

Jein. Es ist richtig, aber es greift zu kurz. Das war auch schon bei dir der Fall. Nur war's falsch. Eine bessere Beschreibung: man erzeugt einen Thread, und ein Objekt, das man an diesen Thread bindet (moveToThread). Danach werden Signal/Slot-Verbindungen von diesem zu Objekten die dem Main-Thread gehoeren sicher uebertragen. WICHTIG DABEI: man muss die Verbindung (signal.connect) NACH dem verschieben des Objektes machen, sonst ist's fuer die Katz!
Antworten