Bei tkinter.messagebox das Tk-fenster verhindern

Fragen zu Tkinter.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Also ich hab schreibe ein skript das sich im hintergrund ausführt (ohne Konsole und ohne GUI).
Wenn es vertig ist kommt eine meldung ob alles geklapt hat oder ob fehler aufgetreten sind. Das mit der ausgabe funkioniert, aber mich nervt das Leere Tk-fenster, läst sich da irgendwas machen? :K
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

kommentier doch den Aufruf der messagebox aus und entferne alle Tk Codeteile, wenn du sie nicht brauchst.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Wie meinst du das? Ich hab bis auf die Message box keinen GUI.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
problembär

Am besten, man macht sich unabhängig:

Code: Alles auswählen

#!/usr/bin/env python
#-*- coding: iso-8859-1 -*-

import Tkinter as tk

class StandaloneMessageBox:

    def __init__(self, title, message):

        self.mw = tk.Tk()
        self.mw.option_add("*font", ("Arial", 15, "normal"))
        self.mw.geometry("+340+240")

        self.mw.title(title)
        self.mw.bind(sequence = "<Control-q>", func = lambda e: self.mw.destroy())
        self.lab1 = tk.Label(self.mw, text = message)
        self.lab1.pack(padx = 30, pady = 30)
        self.btn = tk.Button(self.mw,
                             text = "Ok",
                             command = self.mw.destroy)
        self.btn.bind(sequence = "<Return>", func = lambda e: self.mw.destroy())
        self.btn.focus()
        self.btn.pack(anchor = tk.SE, padx = 10, pady = 10)

        self.mw.mainloop()

if __name__ == "__main__":
    StandaloneMessageBox(title = "Titelzeile", message = "Hallo")
Das ist der Vorteil als Programmierer ;) .
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

problembär hat geschrieben:Am besten, man macht sich unabhängig:
Wenn man auf gut getestete Module verzichten möchte, einem Standardverhalten egal sind, viele Randbereiche ausklammern und noch ordentlich Zeit hat, dann sollte man es wirklich noch einmal selber nachprogrammieren :twisted:
Das Leben ist wie ein Tennisball.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hallo Py-Prog,

das Problem ist der Widerspruch in Deiner Frage.

Entweder Du hast keine GUI, dann gibt es natürlich auch kein Pop-Up Fenster! Alles läuft über Konsole und Du kannst zum Schluss z.B. auf ein Enter warten:

Code: Alles auswählen

raw_input("Erfolgreich beendet, Enter zum Schliessen.")
Bei Fehlern bricht er vorher ab und Du siehst die Ausgabe nicht. Auch nicht den Traceback des des Fehlers, das wurde hier schon in vielen Threads besprochen. Aber das war auch nicht gewünscht, von daher ok.

Das ich öffnende Fenster ist das Hauptprogrammfenster, das immer benötigt wird. Wenn man eine eigene MsgBox in dem Fenster anlegt, ist es zwar noch sichtbar, fällt aber nicht als Programmfenster auf.
Wenn Du die GUI wirklich nur für das eine Nachrichtenfenster brauchst, kannst Du es direkt von Tk ableiten (ersetzt überall self.mw durch self):

Code: Alles auswählen

class StandaloneMessageBox(tk.Tk):

    def __init__(self, title, message):

        tk.Tk.__init__(self)
        [..]
Last but not least: wenn Du keine Modulklasse aufbohren möchtest, kannst Du auch vorher das GUI-Programmobjekt selbst erzeugen und zum Icon verkleinern.

Code: Alles auswählen

def quit_successfully():
    root = tk.Tk()
    root.title("Fenster schliesst automatisch")
    root.protocol("WM_DELETE_WINDOW",0)
    root.iconify()
    tkMessageBox.showinfo(title="Programmende", message="Programm wurde erfolgreich beendet!")
    root.destroy()
Ich persönlich finde aber, dass für die Ausgabe einer Nachricht in einem Fenster das Programmhauptfenster mit Info-Text und Beenden-Button ausreicht. Ist auch nicht so fehleranfällig (GUI-Hauptfenster darf nicht vor der Msg-Box geschlossen werden) und verwirrend (zwei Fenster).
Anders wäre es, wenn es um einen Dateidialog ginge.

Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

[quote="Michael Schneider"]Hallo Py-Prog,

das Problem ist der Widerspruch in Deiner Frage.

Entweder Du hast keine GUI, dann gibt es natürlich auch kein Pop-Up Fenster! Alles läuft über Konsole und Du kannst zum Schluss z.B. auf ein Enter warten:

Code: Alles auswählen

raw_input("Erfolgreich beendet, Enter zum Schliessen.")[/quote]
Das Programm hat [b]keine[/b] Konsole.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Py-Prog hat geschrieben:Das Programm hat keine Konsole.
Welches Programm?

Das Skript hat natürlich keine Konsole, das ist nur Quelltext, evtl. als Bytecode.
Py-Prog hat geschrieben:Also ich hab schreibe ein skript das sich im hintergrund ausführt (ohne Konsole und ohne GUI).
Der Python-Interpreter startet, soviel ich weiß, immer (im Hintergrund) eine Konsole/MS-DOS-Eingabeaufforderung und läuft darin ab, wenn er nicht in ihr gestartet wurde. Mag sein, dass die nicht immer grafisch angezeigt wird, aber da dürfte sie sein. Führst Du .pyw-Dateien aus? Die verstecken die Konsole nämlich.

Und wenn Du aus dem Quellcode per py2exe oder Konsorten eine ausführbare Datei machst, dann ist das (in meinen Augen) kein Python-Skript mehr, sondern ein stinknormales ausführbares Programm, das in Python entwickelt wurde.

Wir sprechen aber nicht davon, dass Du einen Daemon schreibst, oder?

Wie dem auch sei: wenn Du keine GUI verwendest, dann stehen Fenster - und damit Tkinter - nicht zu Deiner Verfügung.

Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Was meinst du mit Dämon?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

Was hast du (Code mässig)? und was willst du genau verhindern? So wie du bis jetzt gefragt hast verstehe ich es nicht und die anderen wahrscheinlich auch nicht (nach den Antworten zu urteilen)...
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Ich will verhindern das das Leere Tk() fenster startet. Und nach eueren antworten zu urteilen geht es nicht und ich muss die ausgabe fenster mit dem Tk() fenster machen damit ich kein leeres fenster auf dem Bildschirm habe.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

ich würde sagen nichts ist unmöglich...
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

ich würde sagen nichts ist unmöglich...
Toyota :lol:

Kann sein das es doch geht, aber du weißt nicht wie, oder doch?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

ich kenne dein konkretes Problem leider immer noch nicht. Ich kann dir doch nicht sagen du sollst im Code die Zeile 93 auskommentieren, wenn ich den Code doch gar nicht kenne.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Py-Prog hat geschrieben:Ich will verhindern das das Leere Tk() fenster startet. Und nach eueren antworten zu urteilen geht es nicht und ich muss die ausgabe fenster mit dem Tk() fenster machen damit ich kein leeres fenster auf dem Bildschirm habe.
Doch, natürlich geht das. Verwende einfach kein Tk.

Warum bindest du Tk ein, wenn du es dann nicht benutzen möchtest?
BlackJack

Ich denke wir haben hier zwei Probleme: Ein OP der das Problem nicht so genau beschreibt wie möglich und Antwortende die Spass am bashen haben, aber sonst halt auch keine Ahnung vom Problem.

Wenn man nur den Dialog haben möchte, geht trotzdem *zusätzlich* noch ein leeres Tk-Hauptfenster auf. Und *das* möchte der OP halt nicht haben. Was ich durchaus nachvollziehen kann.

Das Problem ist, dass Tk-Programme halt immer dieses Hauptfenster haben.

Lösung (mehr oder weniger): Es selber aktiv erzeugen und dann mit der `withdraw()`-Methode unsichtbar machen. Und dann halt erst den Dialog öffnen.
problembär

Py-Prog hat geschrieben:Ich will verhindern das das Leere Tk() fenster startet. Und nach eueren antworten zu urteilen geht es nicht und ich muss die ausgabe fenster mit dem Tk() fenster machen damit ich kein leeres fenster auf dem Bildschirm habe.
Wieso das denn? Ich habe oben doch eine Lösung ohne leeres Tk()-Fenster gepostet!
Kann ja sein, daß EyDu das nicht gefällt, aber vielleicht bildest Du Dir erstmal eine eigene Meinung.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

problembär hat geschrieben:
Py-Prog hat geschrieben:Ich will verhindern das das Leere Tk() fenster startet. Und nach eueren antworten zu urteilen geht es nicht und ich muss die ausgabe fenster mit dem Tk() fenster machen damit ich kein leeres fenster auf dem Bildschirm habe.
Wieso das denn? Ich habe oben doch eine Lösung ohne leeres Tk()-Fenster gepostet!
Kann ja sein, daß EyDu das nicht gefällt, aber vielleicht bildest Du Dir erstmal eine eigene Meinung.
Ich kann Dir nur zustimmen und fühle mich hier langsam aber gehörig veralbert.

Py-Prog: alles was wichtig ist habe ich so deutlich wie kaum irgendwo anders in meinem ersten Post zusammengefasst. Wenn Du das ignorieren willst, bitte. Aber dann brauchst Du Deine Fragen hier auch nicht zu posten.

Nochmal: um eine einfache Textnachricht auszugeben, brauchst Du keine tkMessageBox. Sowas nimmt man in komplexen Programmen, wenn öfters mal Informationen, Warnungen und Fragen aufpoppen sollen. Mach aus dem tk-Haupfenster Dein Message-Window (5 Zeilen Code reichen da aus) und schließ es danach wieder, schon hast Du Dein Ziel erfüllt und kein zuätzliches Fenster.

@BlackJack: ich kann Dir nicht zustimmen, das wir bashen. Unsere Vorschläge sind klar und sachlich formuliert worden.

Gruß,
Michael

ps.: Ein Daemon ist ein Programm, das von einer Konsole ausgekoppelt im Hintergrund läuft. Sowas kann man mit Python auch bewerkstelligen. Davon sollte man aber die Finger lassen, wenn man nicht genau weiß, was man da tut.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Mach ich doch garnicht. Wenn ich kein Tk verwende kommt das leere.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Py-Prog hat geschrieben:Mach ich doch garnicht. Wenn ich kein Tk verwende kommt das leere.
Was machst Du nicht? tkMessageBox, aber kein Tk verwenden? Hast Du Dich schonmal gefragt, woher das 'tk' vor tkMessageBox kommt?
Die tkMessageBox ist im Prinzip auch nur ein zusammengesetztes Tkinter-Widget mit einer einfachen Schnittstelle. Du kannst auch Tkinter.Canvas() initialisieren und, wie ich bereits vorher schrieb, dabei wird als erstes ein Tk-Hauptfenster erzeugt.

Vielleicht war das Dein Denkfehler (tkMessageBox ist Teil von Tkinter).
Wenn Du tkMessageBox unbedingt verwenden möchtest, nimm meine Funktion und verwende 'root.widthdraw()' statt 'root.iconify()', um das Fenster komplett auszublenden. Das 'root.title' und 'root.protocol' kannst Du Dir dann auch sparen.

Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Antworten