Python code erst nach Klick eines Buttons auführen?
Hallo,
ich arbeite gerade an einem Python Skript und komme nicht weiter. Vielleicht kann mir ja jemand Helfen meinen Fehler zu finden.
Ich habe mit Qt Designer eine GUI erstellt mit zwei Combo Boxen. Ich möchte, dass Python erst nach dem Klick des Buttons den Text in der Combo Box als String an eine Variable übergibt. Momentan nimmt er sich den Default Eintrag und speichert diesen in die Variable.
Ich habe hier mal meine "Main Methode":
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import GUI
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = GUI.Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
Attribut1 = ui.Attribut1()
print(Attribut1)
Attribut2 = ui.Attribut2()
sys.exit(app.exec_())
und hier den relevanten Teil der GUI
import key_columns
from PyQt5 import QtCore, QtGui, QtWidgets
from tkinter import *
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 522)
self.Button = QtWidgets.QDialogButtonBox(Dialog)
self.Button.setGeometry(QtCore.QRect(30, 340, 341)
self.Button.setOrientation(QtCore.Qt.Horizontal)
self.Button.setStandardButtons(QtWidgets....)
self.Button.setObjectName("Button")
self.Attribut_1 = QtWidgets.QComboBox(Dialog)
self.Attribut_1.setGeometry(QtCore.QRect(20, 40)
self.Attribut_1.setObjectName("Attribut_1")
self.Attribut_1.addItems(Attribute)
......
self.Button.clicked.connect(self.Attribut1)
def Attribut1(self):
Attribut = self.Attribut_1.currentText()
return Attribut
Müsste nicht dieser "self.Button.clicked.connect(self.Attribut1) Befehl erst nach dem Klick ausgeführt werden? Kann mir jemand den Fehler erklären?
Viele Grüße und Guten Rutsch :)
1 Antwort
Ja, der Code in der Funktion Attribut1 wird nur ausgeführt, wenn der Button sein clicked-Signal auslöst oder wenn die Funktion separat irgendwo aufgerufen wird.
Nun würde ich zunächst einmal hinterfragen, wie du geprüft hast, dass dies so nicht pasiert. Rufst du die Funktion überhaupt noch woanders auf? Als Nebenfrage: Wieso hast du eine Rückgabe für die Funktion definiert?
Was ich auch etwas verwirrend finde, ist, dass du so oft den Namen Attribut... vergeben hast, es gibt neben der Methode sogar eine globale Variable Attribut1. Eindeutigere Namen würden sich doch sicherlich finden lassen?
Und wofür ist der tkinter-Import, wenn du mit Qt doch schon ein GUI-Toolkit eingebunden hast?
(...) und festgestellt, dass dieser geprinted wird bevor ich den Button klicke (...)
Wenn du eine Methode explizit aufrufst, was du ja da auch tust:
Attribut1 = ui.Attribut1()
wird ihr Körper auch ausgeführt. Mit der Bindung an das Signal (clicked) hat das also soweit nichts zu tun. Wenn du die Zeile entfernst, wird die Methode (sofern du nicht noch weitere explizite Aufrufe tätigst), frühestens bei Buttonklick aufgerufen.
Wenn du die Methode weiter so aufrufen möchtest, wie bisher, brauchst du einen Rückgabewert. Methoden, die allerdings nur als Slot verwendet werden, sind normalerweise ohne Rückgabe (denn die wird ja für diese Fälle nicht benötigt).
jaaa ich verstehe. Das Programm lädt sich den Default Text der in der Combo Box auftaucht in Attribut1 und printed den dann.
Ich würde aber eigentlich gerne die Methode weiter so aufrufen. Was kann ich machen, dass er die Methode erst dann aufruft, nachdem ich den Button betätigt habe?
Also eigentlich müsste ich nach
Dialog.show()
eine Art wartebefehl einbauen, sowas wie
sys.wait()
und dann in der setup.UI Funktion einen Befehl, dass er jetzt den Code weiter ausführen soll.
self.Button.clicked.connect(sys.continue())
Wahrscheinlich muss ich mich nochmal in Threading oder sowas einlesen (müsste sowieso mal gemacht werden) aber die Codebeispiele im Internet sehen auf den ersten Blick sehr umfangreich aus. Kann man das nicht auch mit 2-3 Zeilen machen, dass Python wartet bis der Nutzer den Button betätigt hat?
Vielen Dank schonmal für die Tipps. Das hat mich schon weiter gebracht
Wieso du die Methode aufrufen möchtest, wenn sie dann doch nicht ausgeführt werden soll, kann ich nicht nachvollziehen. Entweder du überlässt das den Nutzer (das halte ich für am sinnvollstern) oder führst die Methode selbst aus, ohne auf einen Buttonklick zu warten (und sei es erst nach einer gewissen Wartezeit, dafür lässt sich ein QTimer einsetzen). Also überdenke besser nochmal, was du genau möchtest und was wirklich sinnvoll ist.
Irgendwelche Warteaktionen auf Buttonklicks in extra Threads sind es nicht (sie verschleudern nur Ressourcen, Aufwand und bilden neben schlechtem Design neue potenzielle Fehlerquellen). Führe Aktionen, die erst nach Buttonklick getätigt werden sollen, in den Slots aus. Vermutlich musst du dein Programm etwas umstrukturieren.
Hallo regex,
ich arbeite mit PyCharm und habe hinter Attribut1 = ui.Attribut1() ein print(Attribut1) gesetzt und festgestellt, dass dieser geprinted wird bevor ich den Button klicke. Habe den print Befehl in der Frage ergänzt.
Ich habe mir das mal so gelernt, dass ich eine Funktion immer mit einem return beende, wenn ich am Ende einen Wert haben möchte. Das habe ich aus dem Java Einstiegskurs. Ist es in meinem Fall unschön oder gar falsch?
Das mit dem Attribut und Attribut1 muss ich mal ändern ja.
PyCharm hat sich bei nem frühreren Stadium des Skripts beschwert, dass tkinter nicht eingebunden ist. Aber du hast recht, er läuft jetzt auch ohne.
Ja ich weiß es ist chaotisch, aber ich arbeite daran es übersichtlicher zu machen.
Danke für die Anmerkungen :)