Zurück zu anderem Fenster

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
der_flo
User
Beiträge: 5
Registriert: Mittwoch 17. Februar 2021, 13:49

Guten Tag zusammen,

ich bin erst seit ca. einem halben Jahr mit Python unterwegs und mit PyQT erst ganz frisch. Gerade knabbere ich an Folgendem Problem:

Ich habe ein Eingabefenster, das zu einem 2. Fenster führt. Jetzt möchte ich die Möglichkeit einrichten, von Fenster 2 wieder zurück zu Fenster 1 zu gelangen und eine andere Auswahl zu treffen. Wenn ich die Funktion, welches Fenster 1 wieder öffnet erneut aufrufe bekomme ich den Error:

Code: Alles auswählen

QCoreApplication::exec: The event loop is already running
Hat jemand eine Idee wie ich das Problem lösen kann?


Hintergrund:

GUI erstellt mir QT-Designer
Visual Studio Code
Import UI file mithilfe von:

Code: Alles auswählen

class datei_oeffnen (QDialog):
    
    def __init__(self):
        super(datei_oeffnen,self).__init__()

        loadUi('Start.ui',self)
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Es darf nur ein Exemplar von QApplication geben. Du scheinst da mehrere zu haben.
Wie sieht denn Dein Programm aus? Der Code, den Du zeigst, ist ja nicht sehr hilfreich.
der_flo
User
Beiträge: 5
Registriert: Mittwoch 17. Februar 2021, 13:49

Danke für die schnelle Antwort!

Kann natürlich sein, dass ich etwas Elementares im Umgang mit QApplication nicht verstanden habe. Über VS Code läuft es bisher aber ohne Probleme durch

Ich würde der Einfachheit halber nur die GUI Klassen hier einfügen:

Code: Alles auswählen

class datei_oeffnen (QDialog):
    
    def __init__(self):
        super(datei_oeffnen,self).__init__()

        loadUi('Start.ui',self)
        self.Open.clicked.connect(self.oeffnedatei)
        self.Cancel.clicked.connect(self.end_programm)
        self.show()

    def oeffnedatei(self):
        global fname
        fname=QFileDialog.getOpenFileName(self,'Open file','','CSV Dateien(*.csv)')
        self.close()
    def end_programm(self):
        sys.exit(app.exec_())

app = QApplication(sys.argv)
UIWindow= datei_oeffnen()
app.exec_()

Code: Alles auswählen

def auswahl_kunde ():
    class auswahl_window (QDialog):
        
        def __init__(self):
            super(auswahl_window,self).__init__()

            loadUi('auswahl.ui',self)
        
            global seen
            for x in seen:
                self.combo_kunde.addItem(x)

            
            self.auswertung.clicked.connect(self.auswahl_clicked)
            self.abbrechen.clicked.connect(self.end_programm)
            self.show()
            
        
        def end_programm(self):
            self.close()
        def auswahl_clicked(self):   
            global auswahl
            auswahl = self.combo_kunde.currentIndex()
            self.close()

    app_2 = QApplication(sys.argv)
    UIWindow= auswahl_window()
    app_2.exec_()

Code: Alles auswählen

def Main1 ():
    class main1 (QWidget):
        
        def __init__(self):
            super(main1,self).__init__()

            loadUi('main_window.ui',self)

            .
            .
            .
                
        
        def end_programm(self):
            sys.exit(app_3.exec_())
            
        def neuer_kunde1(self): ## Diese Funktion soll das Fenster 'Auswahl Kunde' öffnen
            auswahl_kunde()
            


    app_3 = QApplication(sys.argv)
    UIWindow= main1()
    app_3.exec_()  
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn ich dieses Namenswirrwarr sehe, wird mir schwindelig.

Und diese lokalen Klassendefinitionen macht man nicht. Sondern zieht die auf die oberste Ebene hoch. Und ruft dann natürlich auch nur EINMAL QApplication auf. So wie es Qt einem auch ansagt.
der_flo
User
Beiträge: 5
Registriert: Mittwoch 17. Februar 2021, 13:49

okay Danke dir!

Ja sorry für das Chaos! habe mit Python bisher nur kleineste Codes im Rahmen von rapid prototyping geschrieben. Das ist zum ersten mal ein etwas umfangreicheres Projekt um mich weiter zu bilden. Danke für das Feedback und die Tipps!
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Variablennamen und Funktionen schreibt man komplett klein, während man Klassen mit großem Anfangsbuchstaben schreibt. Benutze auch keine Abkürzungen, was soll ein fname sein?
Wie ich schon zu Anfang schrieb, darf es nur ein Exemplar von QApplication geben. Wie jetzt main1 mit dateioeffnen zusammenhängt, sehe ich an den Code-Schnippseln nicht, in main1 wird jedenfalls auswahl_kunde aufgerufen, was wiederum ein QApplication-Exemplar erzeugt. Das ist falsch.
Globale Variablen verwendet man nicht. Woher kommt dieses `seen` in auswahl_window? `x` ist ein schlechter Name, egal was in seen drin ist.
Ein Fenster zeigt sich nicht selbst an, das ist etwas, was der Aufrufer macht.
Das ist das, was ich aus den Fragmenten herauslesen konnte: ein Hauptfenster öffnet einen Dialog in dem irgendetwas in eine Combobox eingegeben wird:

Code: Alles auswählen

class AuswahlWindow(QDialog):
    def __init__(self, seen):
        QDialog.__init__(self)
        loadUi('auswahl.ui', self)
        for item in seen:
            self.combo_kunde.addItem(x)
        self.auswertung.clicked.connect(self.auswahl_clicked)
        self.abbrechen.clicked.connect(self.reject)
        self.auswahl = None
            
    def auswahl_clicked(self):   
        self.auswahl = self.combo_kunde.currentIndex()
        self.accept()


class MainWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        loadUi('main_window.ui',self)
        ...
        
    def neuer_kunde1(self):
        seen = [...] # woher das auch immer kommt
        dialog = AuswahlWindow(seen)
        if dialog.exec_():
            auswahl = dialog.auswahl


def main():
    app = QApplication(sys.argv)
    mainwindow = MainWindow()
    app.exec_()

if __name__ == "__main__":
    main()
der_flo
User
Beiträge: 5
Registriert: Mittwoch 17. Februar 2021, 13:49

Danke nochmal an der Stelle! Habe glaube jetzt viel verstanden, was davor unklar war! Der ganze Gulasch ist auch jetzt etwas aufgeräumter.

Das einzige Problem, das ich jetzt noch habe ist, dass ich es nicht hinbekomme, wenn zum zweiten mal eine Auswahl durch die ComboBox getroffen wird, das MainWindow sich mit der richtigen Übergabe wieder öffnet.

DateiOeffnen ist nur das Laden einer CSV Datei, deren Daten im Programm verarbeitet werden. Die Globale Variable werde ich mir einfach durch einen vernünftigen Return sparen
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

der_flo hat geschrieben: Mittwoch 17. Februar 2021, 16:53Das einzige Problem, das ich jetzt noch habe ist, dass ich es nicht hinbekomme, wenn zum zweiten mal eine Auswahl durch die ComboBox getroffen wird, das MainWindow sich mit der richtigen Übergabe wieder öffnet.
Ohne Code läßt sich dazu nichts sagen. Warum sollte sich das Mainwindow wieder öffnen. Das ist die ganze Zeit offen.
der_flo
User
Beiträge: 5
Registriert: Mittwoch 17. Februar 2021, 13:49

Sirius3 hat geschrieben: Mittwoch 17. Februar 2021, 17:59
der_flo hat geschrieben: Mittwoch 17. Februar 2021, 16:53Das einzige Problem, das ich jetzt noch habe ist, dass ich es nicht hinbekomme, wenn zum zweiten mal eine Auswahl durch die ComboBox getroffen wird, das MainWindow sich mit der richtigen Übergabe wieder öffnet.
Ohne Code läßt sich dazu nichts sagen. Warum sollte sich das Mainwindow wieder öffnen. Das ist die ganze Zeit offen.
Okay ich versuch mal die Funktion des Programms zusammen zu fassen:
Es soll mit dem Fenster OeffneDatei eine CSV Datei aus einem Verzeichnis ausgewählt werden. Diese CSV Datei (Kundendaten) wir in einem Block verarbeitet.

Über das Fenster AuswahlWindow soll der Kunde (variable: auswahl) aus einer ComboBox ausgewählt werden, dessen Daten dann im Main Window angezeigt werden sollen. Dem Anwender soll dann die Möglichkeit gegeben werden über einen Button zurück zu AuswahlWindow zu gelangen und einen neuen Kunden zu wählen, dessen Daten dann wieder im MainWindow angezeigt werden usw.
Für die meisten hier vmtl kein Hexenwerk, für mich aber eine Challenge die sich seit paar Tagen zieht. (Naja Semesterferien im Lockdown halt). Ist bis auf den Stress mit dem GUI bisher auch ganz gut gelaufen.

Code: Alles auswählen

class DateiOeffnen (QDialog):
    
    def __init__(self):
        super(DateiOeffnen,self).__init__()

        loadUi('Start.ui',self)
        self.Open.clicked.connect(self.oeffnedatei)
        self.Cancel.clicked.connect(self.end_programm)
        self.show()

    def oeffnedatei(self):
        global filename
        filename=QFileDialog.getOpenFileName(self,'Open file','','CSV Dateien(*.csv)')
        self.close()
    def end_programm(self):
        sys.exit(app.exec_())
        
        
class AuswahlWindow (QDialog):

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

            loadUi('auswahl.ui',self)
        
            global seen
            for item in seen:
                self.combo_kunde.addItem(item)

            
            self.auswertung.clicked.connect(self.auswahl_clicked)
            self.abbrechen.clicked.connect(self.end_programm)
            self.show()
            
        
        def end_programm(self):
            sys.exit(app.exec_())
            
        def auswahl_clicked(self):            
            global auswahl
            auswahl = self.combo_kunde.currentIndex()         
            self.accept()

class MainWindow (QWidget):
        
        def __init__(self):
            super(MainWindow,self).__init__()

            loadUi('main_window.ui',self)

            self.cancel.clicked.connect(self.end_programm)
            self.neuer_kunde.clicked.connect(self.neuer_kunde1)
           



            def show_results() :
                ## ausgabe der Kundendaten

            show_results()
            self.show()
                
        
        def end_programm(self):
            sys.exit(app.exec_())

        def neuer_kunde1(self):
            dialog = AuswahlWindow()
            
            if dialog.exec_():
                global auswahl
                auswahl = dialog.auswahl
            self.accept()
            
            
app = QApplication(sys.argv)





datei_oeffnen= DateiOeffnen()
app.exec_()

filename= filename[0]


# DATENIMPORT

daten=[]
with open (filename, 'r') as fp:
    for zeile in fp:
        daten = list(csv.reader(fp, delimiter=';'))

Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Den grundsätzlichen Aufbau, wie man einen Dialog benutzt, habe ich Dir doch schon gezeigt.
`global` sollte man nicht verwenden und die ganzen end_programm-Methoden sind Quatsch. Zum ersten, weil man sys.exit außerhalb der main-Funktion nicht verwenden sollte, zweitens, weil app.exec_ außerhalb der main-Funktion nichts zu suchen hat und drittens, weil Du dort einfach nur das Fenster schließen willst, bzw. bei einem Dialog accept oder reject aufrufen willst.

Den Dateiöffnen-Dialog verstehe ich immer noch nicht, weil Du dort dort nur einen QFileDialog auf machst.
Antworten