Guten Morgen!
ich bin grade etwas am verzweifeln. Irgendwo habe ich einen gravierenden Denkfehler eingebaut aber verstehe nicht so recht was ich falsch mache. Vielleicht kann mir jemand auf die Sprünge helfen?
[Codebox=python ]
import sys
from PyQt5.QtWidgets import *
from PyQt5.uic import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
def window():
app = QApplication(sys.argv)
try:
widget = loadUi('lm_tauch.ui')
except:
print("Fehler beim Laden der Datei")
widget.show()
widget.btnCalc.clicked.connect(berechnung)
sys.exit(app.exec_())
def berechnung():
print ("berechnung geöffnet")
try:
widget.labelMittelwert.setText('nix')
except:
print ("hat nicht geklappt")
if __name__ == '__main__':
window()
[/Codebox]
Danke schon mal..
Funktion nach Button connect funktioniert nicht...
Für GUI-Programmmierung muss man normalerweise schon objektorientiert arbeiten. Im konkreten hieße das eine Klasse App einzuführen, in welcher du
- widget als self.widget dauerhaft aufbewahrst.
- berechnen als Methode definierst, und darin dann eben auf self.widget zugreifst.
Alternativ kann man in einem so simplen Fall auch mit functools partial arbeiten. Auf Dauer wirst du aber um OO nicht rumkommen.
- widget als self.widget dauerhaft aufbewahrst.
- berechnen als Methode definierst, und darin dann eben auf self.widget zugreifst.
Alternativ kann man in einem so simplen Fall auch mit functools partial arbeiten. Auf Dauer wirst du aber um OO nicht rumkommen.
Vielen Dank für die Antwort. Im Moment geht es mir tatsächlich "nur" darum, mir ein kleines Tool zu schreiben, welches mir ein paar einfache Dinge abnimmt, also eine Email auf Knopfdruck verschicken, eine typische Berechnung mal eben durchzuführen usw. Da ich nicht wirklich ausschließen kann, dass es mal etwas größeres wird, werde ich also versuchen es von Anfang an richtig zu machen.
Andererseits verwundert es mich, dass es nicht so einfach möglich ist wie ich es vor hatte. Ich bin davon ausgegangen, dass die eingebundene ui und die Funktionalitäten überdauern.
Andererseits verwundert es mich, dass es nicht so einfach möglich ist wie ich es vor hatte. Ich bin davon ausgegangen, dass die eingebundene ui und die Funktionalitäten überdauern.
@tt-web: mit Deiner "Fehlerbehandlung" machst Du es ja auch unmöglich, Fehler zu finden. Niemals nackte excepts benutzen. Nur die Fehler abfangen, von denen man auch die Ursache kennt. ein "hat nicht geklappt" sagt nur, da hat was nicht geklappt.
Wenn Du die try-excepts ersatzlos gelöscht hast, kannst Du Dir die Fehlermeldung die kommt mal anschauen und überlegen, warum sie erscheint.
Wenn Du die try-excepts ersatzlos gelöscht hast, kannst Du Dir die Fehlermeldung die kommt mal anschauen und überlegen, warum sie erscheint.
Also ich habe das alles mal so umgesetzt wie ich es für richtig halte ---> Bedeutet es kann trotz Funktionalität hässlich sein und nur zufällig funktionieren (ich bin durchaus selbstkritisch..)
Könnt ihr bitte mal drüber schauen, ob ich grobe Fehler gemacht habe oder ungünstig gearbeitet habe, was mich später dann in irgendwelche Probleme rennen lässt? Das wäre echt super. Danke schon mal..
import sys
from PyQt5.QtWidgets import *
from PyQt5.uic import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
# Erstellen einer Klasse abgeleitet aus QMainWindow
class test(QMainWindow):
#Erstellen eines Objektes der Klasse
def __init__(self):
super().__init__()
self.ui = loadUi('lm_tauch.ui')
self.ui.show()
# Aufrufen von dem was nach dem Knopfdruck passieren soll
self.ui.btnCalc.clicked.connect(self.berechnung)
def berechnung(self):
print ("berechnung geöffnet")
self.ui.labelMittelwert.setText('nix')
# Wird das Programm direkt aufgerufen wird geprüft ob die mainfunktion vorhanden
# ist. Ansonsten wird dieser Block ausgeführt
if __name__ == '__main__':
# Erstellen eines QApplication Objekts, das in 'app' gespeichert wird
app = QApplication(sys.argv)
# Erstellen eines Objektes abgeleitet aus der Klasse test
myapp=test()
# Liefert den Programmexitcode
sys.exit(app.exec_())
Könnt ihr bitte mal drüber schauen, ob ich grobe Fehler gemacht habe oder ungünstig gearbeitet habe, was mich später dann in irgendwelche Probleme rennen lässt? Das wäre echt super. Danke schon mal..
import sys
from PyQt5.QtWidgets import *
from PyQt5.uic import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
# Erstellen einer Klasse abgeleitet aus QMainWindow
class test(QMainWindow):
#Erstellen eines Objektes der Klasse
def __init__(self):
super().__init__()
self.ui = loadUi('lm_tauch.ui')
self.ui.show()
# Aufrufen von dem was nach dem Knopfdruck passieren soll
self.ui.btnCalc.clicked.connect(self.berechnung)
def berechnung(self):
print ("berechnung geöffnet")
self.ui.labelMittelwert.setText('nix')
# Wird das Programm direkt aufgerufen wird geprüft ob die mainfunktion vorhanden
# ist. Ansonsten wird dieser Block ausgeführt
if __name__ == '__main__':
# Erstellen eines QApplication Objekts, das in 'app' gespeichert wird
app = QApplication(sys.argv)
# Erstellen eines Objektes abgeleitet aus der Klasse test
myapp=test()
# Liefert den Programmexitcode
sys.exit(app.exec_())
Bitte lern den Umgang mit dem Code formatting hier. Das ist mit der Vorschaufunktion schnell getan.
Ansonsten ist der Code soweit ok, ein Problem aber ist das laden der ui Datei. Dabei gehts du implizit davon aus, dass das current working directory stimmt. Das tut es aber nicht automatisch. Besser ist, sich Anhand der Variable __name__ mittels os.path.dirname und os.path.join dahin zu hangeln. Das klappt dann immer.
Oh, und du solltest eine echte main Funktion definieren, die du dann nur noch aufrufst. Denn so legts du ungewollt globale Variablen an.
Ansonsten ist der Code soweit ok, ein Problem aber ist das laden der ui Datei. Dabei gehts du implizit davon aus, dass das current working directory stimmt. Das tut es aber nicht automatisch. Besser ist, sich Anhand der Variable __name__ mittels os.path.dirname und os.path.join dahin zu hangeln. Das klappt dann immer.
Oh, und du solltest eine echte main Funktion definieren, die du dann nur noch aufrufst. Denn so legts du ungewollt globale Variablen an.
danke für die Antwort... verdammt ja Da hab ich es so schön kommentiert und das wichtigste dann nicht getan
Ich muss gestehen das mit dem Codeformating ... ja du hast recht... Entschuldigung, ich war da schlampig und hab dir/euch unabsichtlich mehr Arbeit beim Lesen des Codes gemacht.
Vielen Dank für die großartige Hilfe!
LG Thomas
Ich muss gestehen das mit dem Codeformating ... ja du hast recht... Entschuldigung, ich war da schlampig und hab dir/euch unabsichtlich mehr Arbeit beim Lesen des Codes gemacht.
Vielen Dank für die großartige Hilfe!
LG Thomas
Guten Morgen,
jetzt hab ich am Wochenende mal etwas ausprobiert und bin direkt ins nächste Problem reingerannt. Ich wollte dass auf druck des Knopfes sich ein Dialogfeld öffnet:
Zur Information: Den Knopf habe ich in diesem Beispiel durch einen Menüeintrag ersetzt, was aber letztendlich egal sein sollte. Ich sehe, dass sowohl Tauch() als auch tauchapp() aufgerufen wird. Soweit so gut.
In "Tauchapp" habe ich im Prinzip den Code kopiert nur mit dem Unterschied, dass ich eine andere ui-datei lade.
Mir ist aufgefallen, dass es prinzipiell funktioniert, aber der neue Dialog nur kurz angezeigt wird (zumindest ist für Millisekunden ein Fenster zu sehen) und danach gleich wieder geschlossen wird.
Mir ist nicht ganz klar, warum das so passiert und ich würde es gerne verstehen.
Danke schon mal für die Unterstützung, ihr habt mich bisher echt weiter gebracht.
jetzt hab ich am Wochenende mal etwas ausprobiert und bin direkt ins nächste Problem reingerannt. Ich wollte dass auf druck des Knopfes sich ein Dialogfeld öffnet:
Code: Alles auswählen
# Erstellen einer Klasse abgeleitet aus QMainWindow
class test(QMainWindow):
#Erstellen eines Objektes der Klasse
def __init__(self):
super().__init__()
self.lm = loadUi('lm_tauch.ui')
self.lm.show()
# Aufrufen von dem was nach dem Knopfdruck passieren soll
self.lm.actionTauch.triggered.connect(self.Tauch)
def Tauch(self):
print("run tauchapp")
tauchapp()
# Wird das Programm direkt aufgerufen wird geprüft ob die mainfunktion vorhanden
# ist. Ansonsten wird dieser Block ausgeführt
if __name__ == '__main__':
# Erstellen eines QApplication Objekts, das in 'app' gespeichert wird
app = QApplication(sys.argv)
# Erstellen eines Objektes abgeleitet aus der Klasse test
myapp=test()
# Liefert den Programmexitcode
sys.exit(app.exec_())
In "Tauchapp" habe ich im Prinzip den Code kopiert nur mit dem Unterschied, dass ich eine andere ui-datei lade.
Mir ist aufgefallen, dass es prinzipiell funktioniert, aber der neue Dialog nur kurz angezeigt wird (zumindest ist für Millisekunden ein Fenster zu sehen) und danach gleich wieder geschlossen wird.
Mir ist nicht ganz klar, warum das so passiert und ich würde es gerne verstehen.
Danke schon mal für die Unterstützung, ihr habt mich bisher echt weiter gebracht.
@tt-web: Deine Kommentare sind zum größten Teil überflüssig, weil sie nur das beschreiben, was in der nächsten Zeile sowieso steht, im Falle von Zeile 15f sogar einfach nur falsch, da es in Python keine spezielle mainfunktion gibt und somit auch nicht darauf geprüft werden kann. Auch wenn Qt eine andere Namenskonvention hat wie Python, sollte man sich wenigstens an eine von beiden halten, also Klassen werden groß geschrieben und Methoden klein_mit_unterstrich oder kleinUndGroß. Keine Methode darf in einem GUI-Programm blockieren, wenn Du also versuchst eine zweite QApplication mit app.exec_ aufzurufen, wird das schief gehen. Zeig den Dialog mit show an und lass den Rest die Hauptschleife machen.
Guten Morgen,
naja mag sein, dass sie überflüssig sind, aber wenn ich das Projekt liegen lasse und mich in nem Jahr wieder damit beschäftige dann freue ich mich wenn ich auch an einfache Dinge erinnert werde. Den Hinweis mit der Namenskonvention werde ich sofort umsetzen, das ist einfach etwas was ich mir noch angewöhnen muss.
Kannst du mir denn erklären wie die Zeile if __name__ == '__main__': sonst zu interpretieren ist?
Danke schön
naja mag sein, dass sie überflüssig sind, aber wenn ich das Projekt liegen lasse und mich in nem Jahr wieder damit beschäftige dann freue ich mich wenn ich auch an einfache Dinge erinnert werde. Den Hinweis mit der Namenskonvention werde ich sofort umsetzen, das ist einfach etwas was ich mir noch angewöhnen muss.
Kannst du mir denn erklären wie die Zeile if __name__ == '__main__': sonst zu interpretieren ist?
Danke schön
@tt-web: Kommentare geben sinnvollerweise Zusatzinformationen und beschreiben offensichtliches nicht erneut. Die Zeile
ergibt True, wenn das Modul direkt ausgeführt, hingegen False, wenn es per import eingebunden wird. In letzterem Fall enthält __name__ den Namen des Moduls.
Code: Alles auswählen
if __name__ == '__main__':
Danke für die Erklärung. Ich blicke so langsam deutlich besser durch. Jetzt noch eine Frage: Ich bekomme mein zweites Formular angezeigt, kann es aber nicht benutzen.
Warum ist es mir nicht möglich auf den Button zuzugreifen?
Code: Alles auswählen
class Tauch(QDialog):
def tauch(self):
self.ui = loadUi('ui/lm_tauch.ui')
self.ui.show()
self.ui.btnCalc.clicked.connect(self.berechnung)
def berechnung(self)
pass
Hauptfenster:
Aufzurufender Dialog aus modulTauch:
Code: Alles auswählen
import sys
from PyQt5.QtWidgets import *
from PyQt5.uic import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from modulTauch import *
class test(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.lm = loadUi('ui/test.ui')
self.lm.show()
self.lm.actionTauch.triggered.connect(self.tauch)
def tauch(self):
Tauchapp.tauchapp(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
myapp=test()
sys.exit(app.exec_())
Code: Alles auswählen
import sys
from PyQt5.QtWidgets import *
from PyQt5.uic import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from berechnungTauch import *
class Tauchapp(QDialog):
def tauchapp(self):
print("tauchapp")
self.ui = loadUi('ui/lm_tauch.ui')
self.ui.show()
self.ui.btnCalc.clicked.connect(self.berechnung)
def berechnung(self):
print("enter berechnung")
@tt-web: bevor Du hier anfängst, Module kreuz und quer zu importieren, schreib fürs erste alles in eine Datei. Sollte das irgendwann einmal zu viel für eine Datei werden, trenne Dinge ab, die für sich stehen können. Vermeide *-Importe, da Du nicht kontrollieren kannst, was da alles in den Namensraum geladen wird. `show` sollte nicht in __init__ aufgerufen werden. Du erzeugst keine Tauchapp-Instanz sondern versuchst direkt Methoden aufzurufen. Das sollte Dir eigentlich mit einem TypeError um die Ohren fliegen.
Code: Alles auswählen
import sys
import os
from PyQt5.QtGui import QApplication, QDialog, QMainWindow
from PyQt5.uic import loadUi
BASEPATH = os.path.dirname(__file__)
class Tauchapp(QDialog):
def __init__(self):
super().__init__()
print("tauchapp")
loadUi(os.path.join(BASEPATH, 'ui/lm_tauch.ui'), self)
self.btnCalc.clicked.connect(self.berechnung)
def berechnung(self):
print("enter berechnung")
class Test(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
loadUi(os.path.join(BASEPATH, 'ui/test.ui'), self)
self.actionTauch.triggered.connect(self.tauch)
def tauch(self):
Tauchapp().show()
def main():
app = QApplication(sys.argv)
myapp = Test()
sys.exit(app.exec_())
if __name__ == '__main__':
main()