LineEdit-Inhalt über PushButton an ScrollArea übergeben (PyQT5)

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
frcom
User
Beiträge: 49
Registriert: Sonntag 24. September 2017, 19:35

Hallo liebe com,
Ich stehe vor folgendem Problem: Ich habe eine GUI mit 3 LineEdit-Feldern, die ich nach ausfüllen über einen PushButton in eine ScrollArea einschreiben möchte. Mein Code sieht wie folgt aus:

Code: Alles auswählen

class Gauss(QWidget):
    def __init__(self):
        super().__init__()
        self.initMe()

    def initMe(self):
        #Buttons
        self.add_button = QPushButton('add', self)
        self.add_button.setGeometry(QRect(250, 10, 61, 25))
        
        #Inputs
        self.name_in = QLineEdit('Var', self)
        self.name_in.setGeometry(QRect(10, 10, 41, 25))
        self.value_in = QLineEdit('Wert', self)
        self.value_in.setValidator(QIntValidator())
        self.value_in.setGeometry(QRect(70, 10, 78, 25))
        self.error_in = QLineEdit('Fehler', self)
        self.error_in.setValidator(QIntValidator())
        self.error_in.setGeometry(QRect(170, 10, 81, 25))
        
        self.var_scroll = QScrollArea(self)
        self.var_scroll.setGeometry(QRect(10, 70, 301, 131))

        self.add_button.clicked.connect(self.add(self.name_in,
                                                 self.value_in,
                                                 self.error_in))
        
    def add(self, n, v, e):
        pass
        
        self.setGeometry(100, 100, 724, 325)
        self.setWindowTitle('Gauß\'sche Fehlerfortpflanzung')
        self.show()

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    g = Gauss()
    g.show()
    sys.exit(app.exec_())
Ich bekomme aber jedesmal

Code: Alles auswählen

TypeError: argument 1 has unexpected type 'NoneType'
als Fehler. Ich weiß nicht wie ich es hinbekomme die ausgefüllten Felder zusammen als ein String meiner ScrollArea anzufügen. Kann mir da jemand auf diei Sprünge helfen?

Vielen Dank und Grüße!

Edit: Die GUI ist mit PyQt5 entwickelt
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die entscheidende Information in welcher Zeile (nicht nur Nummer, sondern wie die aussieht) teilst du leider nicht mit. Bitte poste den vollen Traceback.

Edit: ich sehe aber schon den Fehler. Beim naechsten mal trotzdem den Traceback posten, dann geht es schneller.

Du willst einen callback angeben, was du aber wirklich machst ist ihn aufzurufen, und den Rueckgabewert (der None ist) als Callback zu setzen.

Du kannst zB mit functools partial einen Callback erzeugen, der die gewuenschten Parameter schon hat, aber eben noch nicht aufgerufen wurde:

Code: Alles auswählen

from functools import partial

def callback(a, b, c):
        print(a*b+c)

...

foo.connect(..., partial(callback, a=10, b=20, c=30))
frcom
User
Beiträge: 49
Registriert: Sonntag 24. September 2017, 19:35

Vielen Dank! Und klar werde ich nächstes Mal den ganzen Traceback rein packen, hab nicht weiter gedacht...
Das mit functools funktioniert soweit, allerdings muss es doch eine andere Möglichkeit ohne ein weiteres Modul geben erst die LineEdits auszufüllen und dann der Buttonfunktion deren Inhalt mitzuteilen oder nicht?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Warum? Das ist ein Standardbibliothek-Modul. Das ist immer da.

Aber grundsätzlich klar - du kannst auch über Self arbeiten.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@frcom: Ich finde die ganzen `setGeometry()`-Aufrufe ja ein wenig suspekt. Das ist keine gute Idee. Zum einen wird sowas zum Albtraum wenn man die GUI mal umgestalten will/muss, zum anderen funktionieren diese absoluten Angaben auf anderen Rechnern nicht zwingend wenn die andere Auflösungen und/oder Einstelllungen wie beispielsweise Schriftgrösse haben. Qt hat dafür Layouts.

Warum ist das was eigentlich in die `__init__()` gehört in eine `initMe()`-Methode ausgelagert? Das macht keinen Sinn.

`g`, `n`, `v`, und `e` sind keine sinnvollen Namen. So etwas kann man manchmal machen wenn der Gültigkeitsbereich sehr klein ist, zum Beispiel in ``lambda``- oder Generatorausdrücken, aber für normale lokale Namen oder Argumente geht das nicht.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
frcom
User
Beiträge: 49
Registriert: Sonntag 24. September 2017, 19:35

Also @__blackjack__, du hast natürlich recht... die ganzen 'setGeometry()'-Aufrufe sind nicht wirklich sinnvoll, ich hab das Ganze jetzt nochmal geändert:

Code: Alles auswählen

class WidgetGallery(QWidget):
    def __init__(self):
        super(WidgetGallery, self).__init__()
        
        self.originalPalette = QApplication.palette()
        
        self.createTopLeftGroupBox()
        self.createTopRightGroupBox()
        self.createBottomLeftTabWidget()
        self.createBottomRightGroupBox()
        
        topLayout = QHBoxLayout()
        topLayout.addStretch(1)
        
        mainLayout = QGridLayout()
        mainLayout.addLayout(topLayout, 0, 0, 1, 2)
        mainLayout.addWidget(self.topLeftGroupBox, 1, 0)
        mainLayout.addWidget(self.topRightGroupBox, 1, 1)
        mainLayout.addWidget(self.bottomLeftTabWidget, 2, 0)
        mainLayout.addWidget(self.bottomRightGroupBox, 2, 1)
        mainLayout.setRowStretch(1, 1)
        mainLayout.setRowStretch(2, 1)
        mainLayout.setColumnStretch(0, 1)
        mainLayout.setColumnStretch(1, 1)
        self.setLayout(mainLayout)
        
    def createTopLeftGroupBox(self):
        self.topLeftGroupBox = QGroupBox('add variable')
        
        self.var_in = QLineEdit('')
        self.value_in = QLineEdit('')
        self.value_in.setValidator(QIntValidator())
        self.error_in = QLineEdit('')
        self.error_in.setValidator(QIntValidator())
        
        add_button = QPushButton('add variable')
        
        layout = QVBoxLayout()
        layout.addWidget(self.var_in)
        layout.addWidget(self.value_in)
        layout.addWidget(self.error_in)
        layout.addWidget(add_button)
        layout.addStretch(1)
        self.topLeftGroupBox.setLayout(layout)
    
######von hier###################################
        self.a = self.var_in.textChanged.connect(self.var_function)      
        
        add_button.clicked.connect(self.add_function)
        
    def add_function(self, a):
        print(self.a)
        
    def var_function(self, text):
        return self.var_in.text()
######bis hier###################################
        
    def createTopRightGroupBox(self):
        self.topRightGroupBox = QGroupBox('calculation')
        
        calc_in = QLineEdit('input formula')
        
        calc_button = QPushButton('calculate')
        
        layout = QVBoxLayout()
        layout.addWidget(calc_in)
        layout.addWidget(calc_button)
        layout.stretch(1)
        self.topRightGroupBox.setLayout(layout)
    
    def createBottomLeftTabWidget(self):
        self.bottomLeftTabWidget = QGroupBox('added variables')
    
    def createBottomRightGroupBox(self):
        self.bottomRightGroupBox = QGroupBox('history')
        
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    gallery = WidgetGallery()
    gallery.show()
    sys.exit(app.exec_())
womit ich nicht weiter komme ist der markierte teil... ich bekomme beim click auf den Button nicht den input sondern ein 'none'-Wert geliefert und verstehe nicht so ganz warum und wie ich da den input zurück geben kann :/
dankbar für jede Hilfe!
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

So funktioniert das Signal-Slot-System von Qt nicht und auch keine sonstige Event-gesteuerte GUI. Der Rückgabewert von connect, den Du an `self.a` bindest ist None, weil connect keinen Rückgabewert hat. Der Rückgabewert einer Event-Methode wird normalerweise einfach ignoriert, weil, an was soll den der Wert zurückgegeben werden?

Die Parameter a und text von add_function und var_function sind irreführend. Lies mal nach, welche Parameter Event-Methoden haben. Den Nutzen von var_function sehe ich generell nicht, weil Du beim Drücken auf den Knopf den Inhalt des Edit-Feldes direkt auslesen könntest.
frcom
User
Beiträge: 49
Registriert: Sonntag 24. September 2017, 19:35

mh, wie kann ich denn den inhalt direkt auslesen? @sirius3 das ist im Prinzip alles was ich brauche :roll:
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das was Du in `var_function()` machst kannst Du doch einfach direkt in `add_function()` machen. Eben den Wert aus der GUI abfragen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten