Qt Python Programm funktioniert nach Umstieg von Windows auf Mac OS nicht mehr

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Gironimo
User
Beiträge: 8
Registriert: Montag 15. April 2019, 21:58

Montag 15. April 2019, 22:14

Hallo!

Ich bin von Windows auf Mac OS umgestiegen. Nun funktionieren meine Qt Programme nicht mehr :( .
Meine Kommandozeilenprogramme funktionieren einwandfrei aber die Qt Programme nicht mehr.
Ich schreibe in PyCharm unter Windows und jetzt auch unter Mac OS. In PyCharm kann ich es ausführen, es startet auch aber wenn ich Buttons klicke machen sie nicht das was Sie sollen(bis auf Exit Button).
Hat jemand eine Idee woran es liegen kann?

Hier mal mein Github mit dem Programm: https://github.com/Gir0nim0/Sudhausrechner

Danke im voraus. Mit freundlichen Grüßen, Jan
Benutzeravatar
__blackjack__
User
Beiträge: 3882
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 17. April 2019, 11:57

Also unter Linux scheint es zu funktionieren, aber die GUI ist ziemlich kaputt weil Du anscheinend keine Layouts sondern absolute Grössen und Positionen verwendest:
Bild
Das solltest Du ändern.

Was passiert denn wenn Du das ausserhalb einer IDE in einer Konsole startest? Wird da etwas ausgegeben wenn Du „berechnen“ klickst?
“There's also a certain pleasure in actually getting things to work in Java, somewhat like the pleasure, I imagine, of building ships in bottles.”
— David Cook in c.l.p
Gironimo
User
Beiträge: 8
Registriert: Montag 15. April 2019, 21:58

Mittwoch 17. April 2019, 19:37

Hallo!

Danke, dass du es dir mal angeschaut hast.

Also bei mir startet es auch. Aber wenn ich die Felder für die Berechnung der Sudhausausbeute fülle und auf berechnen klicke wird darunter nichts angezeigt. Das ist in der IDE so und auch beim ausführen über eine Konsole. Ich hab jetzt mal ein print() eingefügt um mal zu schauen ob der Button funzt. Das macht er. Aber das Ergebnis wird nicht ins Label geschrieben, was unter der Zeile unter dem Button ist.

Ich glaube echt, dass es ein Mac Ding ist. Denn IDE und Python Version sind identisch. :roll:

Ich komm gerade echt nicht weiter :(

Gruß Jan
Benutzeravatar
__blackjack__
User
Beiträge: 3882
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Donnerstag 18. April 2019, 14:16

@Gironimo: Hast Du das auch in einer Konsole ausgeführt und nicht aus einer IDE heraus? Und wo war das `print()` platziert? Nach dem Setzen des Labeltextes, also das Du sicher bist, das der Code auch bis dort hin gekommen ist? Ist das Label auch tatsächlich sichtbar? Welche Qt-Anbindung wird denn letztendlich verwendet? PyQt oder PySide und in welcher Version? Ist *das* auch auf den Rechnern gleich?

Warum generierst Du aus der *.ui-Datei eigentlich eine Python-Datei? Man kann doch auch einfach die *.ui-Datei zur Laufzeit laden.

Für die Eingaben von Gleitkommazahlen würde ich einen `QDoubleSpinner` verwenden. Da kann man dann auch gleich die Einheiten mit in die Anzeige packen. Und mittels `QLocale` kann man Anzeige und Umwandlung verbessern, so das man nicht immer das Dezimalkomma durch einen Dezimalpunkt ersetzen muss.

Das Ergebnis könnte man auch in „read only“-”Eingabe”feldern anzeigen. Da ist dann auch gleich die Masseinheit drin, und man kann dort die Anzahl der Nachkommastellen angeben und kann sich das runden sparen. Zudem kann der Benutzer das Ergebnis aus dem Feld in die Zwischenablage kopieren. Was auch bei der bisherigen Darstellung in Labels eine nette Idee wäre: man kann das auf `QLabel` mit `setTextInteractionFlags()` ermöglichen.

Man könnte sich vielleicht auch die „berechnen“-Schaltflächen sparen, wenn man einfach bei allen Änderungen in den Eingabefeldern das Ergebnis versucht neu zu berechnen. Dann hat der Benutzer einen Klick weniger und braucht nur die Zahlen einzutragen.

Ich würde auch die Geschäftslogik von der GUI trennen. Also im Grunde ja nur ein paar Funktionen mit den Formeln.

Die „Exit“-Schaltfläche wird mit der `exit()`-Funktion verbunden: das ist falsch. Erstens gibt es diese Funktion eigentlich gar nicht – die ist nicht dokumentiert und nur da weil die interaktive Python-Shell die anbietet. Und zweitens beendet die das Programm hart, ohne Rücksicht auf Qt zu nehmen. Dessen Hauptschleife wird also nicht geordnet verlassen. Ich würde die Schaltfläche einfach mit der `close()`-Methode des Fensters verbinden. Standardeinstellung von Qt ist, dass die Anwendung beendet wird, wenn kein Fenster mehr offen ist.
“There's also a certain pleasure in actually getting things to work in Java, somewhat like the pleasure, I imagine, of building ships in bottles.”
— David Cook in c.l.p
Gironimo
User
Beiträge: 8
Registriert: Montag 15. April 2019, 21:58

Dienstag 23. April 2019, 19:37

Vielen Dank für deine zahlreichen Denkanregungen.
Ich programmiere seit ca. 5 Monaten mit Python und habe quasi keine Vorerfahrungen. Mein Wissen hab ich aus einem für mich sehr guten Udemy Kurs. Und es macht mir auch sehr viel Spaß. Deswegen hatte ich vor, Optimierungen am Code und Programmaufbau erst zu machen, wenn ich mehr Durchblicke und mehr Erfahrung gesammelt habe.
Die Idee mit dem print() nach dem Label setzen Befehl hatte ich auch schon um zu gucken, ob es im Code weiter geht. Ja! Macht er.
Ich bin jetzt durch Zufall drauf gestoßen, dass das Ergebnis im Label erscheint wenn ich das Fenster inaktiv setze. Sprich, wenn ich mit der Maus auf den Desktop klick und somit das aktive Fenster Grau wird. Komisches Phänomen. Alle meine Recherchen sind irgendwie im Sande verlaufen.

Gruß, Jan

P.S.: Danke für den Hintergrund zum Exit-Befehl
Benutzeravatar
__blackjack__
User
Beiträge: 3882
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Dienstag 23. April 2019, 21:44

Hast Du das Programm auch schon mal ohne IDE ausgeführt?
“There's also a certain pleasure in actually getting things to work in Java, somewhat like the pleasure, I imagine, of building ships in bottles.”
— David Cook in c.l.p
Gironimo
User
Beiträge: 8
Registriert: Montag 15. April 2019, 21:58

Mittwoch 24. April 2019, 21:16

Ja! Ich starte es unter Mac mit dem Python Launcher, der bei Python3.7 dabei ist. Dort das selbe in Grün. Es ist auch bei beiden die 3.7.
Gironimo
User
Beiträge: 8
Registriert: Montag 15. April 2019, 21:58

Sonntag 28. April 2019, 19:13

__blackjack__ hat geschrieben:
Donnerstag 18. April 2019, 14:16

Warum generierst Du aus der *.ui-Datei eigentlich eine Python-Datei? Man kann doch auch einfach die *.ui-Datei zur Laufzeit laden.


Ich würde auch die Geschäftslogik von der GUI trennen. Also im Grunde ja nur ein paar Funktionen mit den Formeln.

@__blackjack__ : Kannst du mir vielleicht mal zeigen wie du das meinst?!
__deets__
User
Beiträge: 6059
Registriert: Mittwoch 14. Oktober 2015, 14:29

Montag 29. April 2019, 11:53

Fuer mich mit brew python 3.7 und PyQt5 (direkt genutzt durch Anpassung des imports) funktioniert's mit macOS.
Benutzeravatar
__blackjack__
User
Beiträge: 3882
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Freitag 3. Mai 2019, 13:45

@Gironimo: Zum laden von *.ui-Dateien zur Laufzeit gibt es das `qtpy.uic`-Modul und dort die `loadUi()`-Funktion.

Trennung von GUI und Programmlogik sind im Grund ja nur die Berechnungen, die man in eigene Funktionen heraus ziehen sollte, die dann nichts mit der GUI zu tun haben.
“There's also a certain pleasure in actually getting things to work in Java, somewhat like the pleasure, I imagine, of building ships in bottles.”
— David Cook in c.l.p
Gironimo
User
Beiträge: 8
Registriert: Montag 15. April 2019, 21:58

Montag 6. Mai 2019, 19:57

__blackjack__ hat geschrieben:
Freitag 3. Mai 2019, 13:45
@Gironimo: Zum laden von *.ui-Dateien zur Laufzeit gibt es das `qtpy.uic`-Modul und dort die `loadUi()`-Funktion.

Trennung von GUI und Programmlogik sind im Grund ja nur die Berechnungen, die man in eigene Funktionen heraus ziehen sollte, die dann nichts mit der GUI zu tun haben.
Top! Danke
Gironimo
User
Beiträge: 8
Registriert: Montag 15. April 2019, 21:58

Montag 13. Mai 2019, 15:40

Kann mir vielleicht jemand mal ein Beispiel geben für den Import mittels loadUi()?!
Ich stell mich irgendwie zu doof an und das Netz bringt mich auch irgendwie nicht weiter.

Danke im voraus.


Gruß Jan
Benutzeravatar
__blackjack__
User
Beiträge: 3882
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Montag 13. Mai 2019, 17:55

@Gironimo: Wo liegt denn das Problem? Die Funktion hat im einfachsten Fall nur ein Argument – den Dateinamen, und liefert dann die GUI aus der Datei als Rückgabewert. Also wenn in der *.ui-Datei ein `QDialog` mit Inhalt definiert ist, bekommt man ein `QDialog`-Exemplar zurück geliefert. Und das hat die ganzen Namen die man für die Widgets darin im Designer festgelegt hat als Attribute. Also in Deinem Fall `exitButton`, `buttonFlaschenrechner`, `inputAnzahl1L`, und so weiter.

Alternativ kann man als zweites Argument, neben dem Dateinamen auch ein Objekt angeben das für die oberste Ebene verwendet werden soll. Das muss dann vom gleichen Typ sein wie die Wurzel in der *.ui-Datei, also `QDialog` und dann werden auch auf *dem* Objekt all die Attribute für die einzelnen Teile gesetzt. Dann sollte man den Rückgabewert ignorieren, denn sonst hat man zwei verschiedene Wege um an die gleichen Werte zu kommen, was verwirrend und überflüssig ist.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import sys

from PyQt5.QtWidgets import QApplication
from PyQt5.uic import loadUi

def main():
    app = QApplication(sys.argv)
    dialog = loadUi('Sudhausrechner.ui')
    dialog.exitButton.clicked.connect(dialog.close)
    # ...
    dialog.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
Hierbei muss das Arbeitsverzeichnis das sein wo auch die ui-Datei liegt, ansonsten muss man mit dem Wert von `__file__` und den Funktionen aus `os.path` einen relativ zum Modul basteln. Und für eine sinnvolle Anwendung wird man eine Klasse schreiben wenn man nicht mit `functools.partial()` das `QDialog`-Objekt an die Rückruffunktionen für die Berechnungen binden möchte.

Alternative:

Code: Alles auswählen

#!/usr/bin/env python3
import sys

from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.uic import loadUi


class SudhausrechnerUi(QDialog):
    
    def __init__(self):
        QDialog.__init__(self)
        loadUi('Sudhausrechner.ui', self)
        self.exitButton.clicked.connect(self.close)
        # ...


def main():
    app = QApplication(sys.argv)
    gui = SudhausrechnerUi()
    gui.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
“There's also a certain pleasure in actually getting things to work in Java, somewhat like the pleasure, I imagine, of building ships in bottles.”
— David Cook in c.l.p
Gironimo
User
Beiträge: 8
Registriert: Montag 15. April 2019, 21:58

Dienstag 14. Mai 2019, 03:48

Danke für die schnelle Antwort!

Vergiss mal bitte nicht, dass ich neu auf dem Gebiet bin. Insbesondere Gut ist Neuland. Ich werde mir das heute Abend mal zu Gemüte führen.
Ich danke für die ausführliche Erklärung.

Gruß Jan
Antworten