Mehrere selbsterstellte Widgets in GUI einbinden

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
markus24
User
Beiträge: 6
Registriert: Mittwoch 9. März 2011, 10:03

Hallo,

ich bin gerade dabei ein GUI mit selbsterstellten Widgets zu erstellen. Dazu habe ich 4 LED und 4 Checkboxen in einem GridLayout zusammengefasst. Zusätzlich habe ich noch ein Signal im Widget eingeführt, dass bei Benutzung einer Checkbox eine Funktion im GUI ausführt.

Bild

Code: Alles auswählen

from python_lib.ledwidget import LED
from PySide import QtGui, QtCore

class MYLEDS(QtGui.QWidget):
    outchangedSignal = QtCore.Signal(int)
    
    def __init__(self, parent):
        super(MYLEDS, self).__init__(parent)
        self.iaddr = 0
        self.initUI()
        
    def initUI(self):
        self.led1 = LED(self)
        self.led2 = LED(self)
        self.led3 = LED(self)
        self.led4 = LED(self)
        
        self.addr = QtGui.QLabel(str(self.iaddr))
        
        self.o3   = QtGui.QCheckBox('')
        self.o2   = QtGui.QCheckBox('')
        self.o1   = QtGui.QCheckBox('')
        self.o0   = QtGui.QCheckBox('')
                
        hbox = QtGui.QGridLayout(self)
        hbox.addWidget(self.addr, 0, 0)
        hbox.addWidget(self.led1, 0, 1)
        hbox.addWidget(self.led2, 0, 2)
        hbox.addWidget(self.led3, 0, 3)
        hbox.addWidget(self.led4, 0, 4)
        hbox.addWidget(self.o3  , 0, 5)
        hbox.addWidget(self.o2  , 0, 6)
        hbox.addWidget(self.o1  , 0, 7)
        hbox.addWidget(self.o0  , 0, 8)
        
        QtCore.QObject.connect(self.o3,  QtCore.SIGNAL("stateChanged(int)"), self.output_changed)
        QtCore.QObject.connect(self.o2,  QtCore.SIGNAL("stateChanged(int)"), self.output_changed)
        QtCore.QObject.connect(self.o1,  QtCore.SIGNAL("stateChanged(int)"), self.output_changed)
        QtCore.QObject.connect(self.o0,  QtCore.SIGNAL("stateChanged(int)"), self.output_changed)
        
    def setAddr(self, addr):
        self.iaddr = addr
        self.addr.setText(str(self.iaddr))
        
    def output_changed(self):
        out0 = int(self.o0.checkState())
        out1 = int(self.o1.checkState())
        out2 = int(self.o2.checkState())
        out3 = int(self.o3.checkState())
        
        self.outchangedSignal.emit(self.iaddr)
        
    def input_changed(self, state):
        pass
Im Gui steht:

Code: Alles auswählen

for i in range(15):
    widget = myleds.MYLEDS(self)
    widget.setAddr(i)
    self.ui.testLayout.addWidget(widget)

QtCore.QObject.connect(widget, QtCore.SIGNAL('outchangedSignal(int)'), self.test)
Nun möchte ich dieses Widget bis zu 60mal auf einer GUI benutzten. Gibt es da einen einfachen Weg, ohne das Widget 60 mal zu definieren. Da ich von dem Widget den Zustand der Checkboxen und die ID per Signal erhalt benötige ich eigentlich nur eine Schleife in der ich das Widget 60mal auf das GUI platziere.

Definiere ich das Widget nur einmal und lasse es durch eine Schleife platzieren, bekomme ich nur vom letzten Widget die Signal, da ich die vorhergehenden überschreibe.

Danke im Voraus
Markus
EmaNymton
User
Beiträge: 174
Registriert: Sonntag 30. Mai 2010, 14:07

Genau vor dem gleichen Problem stand ich auch, der folgende Thread zeigt zwei Möglichkeiten auf und lässt sich auf dein Problem übertragen:
http://www.python-forum.de/viewtopic.php?f=24&t=20512

Gruß
EmaNymton
markus24
User
Beiträge: 6
Registriert: Mittwoch 9. März 2011, 10:03

Hallo,

Danke für den Tipp. Ich habe den Vorschalg von lunar implementiert und es funtioniert soweit.

Code: Alles auswählen

...
spin.valueChanged[int].connect(partial(self.slot_show, spin, tag)))
...
Jetzt bekomme ich die Informationen von meinem Widget an das GUI. Jetzt fehlt mir nur noch das Verständins, wie ich die Informationen von meinem GUI an mein Widget sende. Ich möchte mit diesem Signal die LED ein und ausschalten.

Grüße
Markus
markus24
User
Beiträge: 6
Registriert: Mittwoch 9. März 2011, 10:03

Hallo,

hat den keiner eine Idee, wie ich die Signale zurück in meine vielen Widgets bekommen?

Danke
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich kapiere Dein Problem nicht.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
markus24
User
Beiträge: 6
Registriert: Mittwoch 9. März 2011, 10:03

Hallo,

ich versuche es nochmal zu beschreiben.

Ich habe 60 Widget (4 Checkboxes, 4 LED) in meinem MainWindow. Wenn ich eine Checkbox in irgendeinen dieser vielen Widgets anklicke erhalte ich die ID (1 - 60) des Widgets und den Zustand aller Checkboxen (1001) .

Code: Alles auswählen

    for i in range(60):
        widget = myleds.MYLEDS(self)
        self.ui.tableWidget.insertColumn(i); widget.setAddr(str(i+1))
        self.ui.tableWidget.setCellWidget(0, i, widget)
        widget.outchangedSignal[str, str].connect(self.test)
Die Funktion self.test gibt mir die zwei Argumente per print aus:

Code: Alles auswählen

    def test(self, arg, arg2):
        print str(arg), str(arg2)
Nun möchte ich aber auch den Zustand der LEDs ändern. Schwarz ist aus, Rot ist Fehler, Grün ist OK.
Wie setzte ich jetzt mit Angabe der ID des Widgets die einzelnen LEDs? Da ich nicht jedes Widget einzeln platzieren möchte, müsste eine entsprechende Funktion die LED pro Widget setzen.

Ich bekomme von meinem Prozesse die Information, das bei IDx 2 von 4 LED grün sind und der Rest rot. Da ich alle 60 Widgets in einer Schleife auf das GUI platziere, habe ich doch keinen Bezug mehr auf die einzelnen Widget. Damit kann ich doch nicht mehr mit einer Funktion auf auf das einzelne Widget zugreifen und den Status setzen, oder?

Denke ich etwa falsch, oder gibt es eine bessere Lösung?

Danke
Markus
Zuletzt geändert von markus24 am Mittwoch 16. März 2011, 15:02, insgesamt 1-mal geändert.
BlackJack

@markus24: Also ich habe auch immer noch nicht verstanden was Du eigentlich machen willst. :K
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also wenn Du aus dem Programm heraus Werte in den einzelnen Widgets setzen willst, brauchst Du natürlich Zugriff auf das entsprechende Objekt. Ich habe Dir mal ein kleines Demo-Script geschrieben, welches da zwei Arten zeigt.

Du kannst also entweder die Objekte aus dem Layout heraus "anonym" per Index rausholen, oder aber diese gezielt in einer Liste (o.ä.) verwalten.

Ich hoffe ich habe das jetzt richtig verstanden?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
markus24
User
Beiträge: 6
Registriert: Mittwoch 9. März 2011, 10:03

Danke,

ich glaube, das ist das was ich gesucht habe.

Gruß Markus :D
Antworten