Wie zeigen immer wieder den Dialog mit PyGTK / Gtkbuilder?
Habe ich eine PyGTK-Anwendung, die zeigt, dass ein Dialog, wenn der Benutzer eine Taste drückt.
Der dialog geladen wird, in meinem __init__
Methode mit:
builder = gtk.Builder()
builder.add_from_file("filename")
builder.connect_signals(self)
self.myDialog = builder.get_object("dialog_name")
In der event-handler, wird der dialog angezeigt, mit dem Befehl self.myDialog.run()
, aber das funktioniert nur einmal, denn nach run()
wird der dialog automatisch zerstört. Wenn ich auf die Taste ein zweites mal, stürzt die Anwendung ab.
Habe ich gelesen, dass es einen Weg gibt, zu verwenden show()
statt run()
wo der dialog wird nicht zerstört, aber ich glaube, das ist nicht der richtige Weg für mich ist, weil ich möchte, dass der dialog zu Verhalten, Modal und Rückgabe der Kontrolle an den code erst, nachdem es vom Benutzer geschlossen wurde.
Gibt es eine einfache Möglichkeit, um immer wieder einen dialog mit der run()
Methode mit gtkbuilder? Ich habe versucht das Neuladen der ganze dialog mit dem gtkbuilder, aber das hat nicht wirklich zu funktionieren scheint, war der dialog fehlt, werden alle untergeordneten Elemente (und ich würde es vorziehen, verwenden Sie den generator nur einmal am Anfang des Programms).
[LÖSUNG] (bearbeitet)
Wie bereits durch die Antwort unter Verwendung hide()
funktioniert der trick. Ich dachte zuerst, Sie musste noch fangen Sie die "delete-event", aber dies in der Tat nicht notwendig. Ein einfaches Beispiel, das funktioniert:
import pygtk
import gtk
class DialogTest:
def rundialog(self, widget, data=None):
self.dia.show_all()
result = self.dia.run()
self.dia.hide()
def destroy(self, widget, data=None):
gtk.main_quit()
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("destroy", self.destroy)
self.dia = gtk.Dialog('TEST DIALOG', self.window,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.dia.vbox.pack_start(gtk.Label('This is just a Test'))
self.button = gtk.Button("Run Dialog")
self.button.connect("clicked", self.rundialog, None)
self.window.add(self.button)
self.button.show()
self.window.show()
if __name__ == "__main__":
testApp = DialogTest()
gtk.main()
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eigentlich, Lesen Sie die Dokumentation auf
Dialog.run()
. Der dialog ist nicht automatisch zerstört. Wenn Siehide()
es, wenn dierun()
- Methode sich beendet, dann sollten Sie in der Lage sein, umrun()
es so oft wie Sie wollen.Alternativ können Sie den dialog modal sein in Ihrem builder "Datei" und dann nur
show()
es. Dadurch wird die Wirkung erzielen, die ähnlich, aber nicht ganz das gleiche wierun()
- weilrun()
schafft eine zweite Instanz des Haupt-GTK-Schleife.BEARBEITEN
Der Grund, warum Sie werden immer ein segmentation fault, wenn Sie nicht die Verbindung zum
delete-event
signal ist, dass Sie Klick auf den schließen-Knopf zweimal. Hier ist, was passiert:run()
Methode.run()
überschreibt das normale Verhalten der schließen-Schaltfläche, das Dialogfeld wird nicht geschlossen. Es ist auch nicht ausgeblendet, so hängt er herum.run()
ist nicht mehr aktiv, das normale Verhalten der schließen-Schaltfläche ausgelöst wird: der dialog zerstört wird.run()
Methode der zerstörten dialog. Crash!Wenn Sie also stellen Sie sicher, dass
hide()
den dialog nach Schritt 3, dann sollte alles funktionieren. Es gibt keine Notwendigkeit zu verbinden mit derdelete-event
signal.self.dia.connect("delete-event", self.closedialog)
bekomme ich ein "Segmentation Fault" das zweite mal, dass ich auf die Schaltfläche klicken. So ETWAS zerstört worden ist, ohne mich, es zu tun, richtig? Danke für deine Klarstellungen, die durch die Art und Weise.closedialog
- Funktion zu verzichten und setzenself.dia.hide()
nach derrun()
nennen. Dies zu tun, was Sie wollen. Das problem ist, dass Sie auf die Schaltfläche schließen zweimal, wenn man den segfault. Siehe meine bearbeitete Antwort für den Grund, warum.Ich habe gerade einige Zeit damit verbracht, herauszufinden dieses heraus. Wieder-Holen Sie das gleiche Objekt von einem generator erstellt eine neue Instanz des Objekts, sondern nur einen Verweis auf den alten (zerstörten) Objekts. Wenn Sie einen neuen builder-Instanz, jedoch, und laden Sie Ihre Datei in das neue generator, es wird eine neue Instanz erstellen.
Also meine Dialogfeld Schaffung Funktion sieht ungefähr so aus:
Beachten Sie, dass ich bin nicht blockiert, für eine Antwort mit run() in diesem Fall, denn ich bin mit verdreht, aber es sollte gleichwertig sein.
Ihr Dialogfeld sollte müssen nur einmal ausgeführt wird. Vorausgesetzt wird ein Menüpunkt löst den dialog, der code sollte wie folgt Aussehen:
dialog.run()
ist eine Sperrung der main-Schleife, zurück, wenn der dialog zum senden einer Antwort. Dies geschieht in der Regel über die Schaltflächen Ok und Abbrechen. Wenn dies geschieht, ist der dialog beendet und muss zerstört werden.Zeigen, den dialog immer wieder, sollte der Nutzer Folgen den gleichen workflow (im obigen Beispiel wäre das der Klick auf einen Menüpunkt). Der dialog zuständig ist, in
__init__
, für die Einstellung selbst einrichten. Wenn Siehide()
den dialog, Sie haben das problem der Kommunikation, der dialog, also bleibt up-to-date mit dem rest der Anwendung , auch wenn es versteckt.Einer der Gründe, einige Leute wollen, "führen Sie den dialog immer wieder" ist, da der Benutzer eingegeben hat ungültige Daten, und Sie möchten, um den Benutzer die Möglichkeit, es zu korrigieren. Diese müssen behandelt werden, in der dialog-Antwort-signal-handler. Die Reihenfolge der Ereignisse in einem dialog:
gtk.RESPONSE_OK
(-5)run()
Methode gibt die AntwortUm zu verhindern, dass die Schritte 4 und 5 passiert, wird der response-handler müssen unterdrücken das response-signal. Dies wird wie folgt erreicht: