Seite 1 von 1

Widgets mit pack vor "zusammenschieben" schützen?

Verfasst: Donnerstag 2. Oktober 2008, 08:29
von gego2
Hallo zusammen,

es gibt ja eine ganze Menge an grundlegenden Einführungen in Tkinter - die wenigsten propagieren, pack zu benutzen ... ich tue es trotzdem, unter anderem, weil es simpel ist, also wie für mich gemacht.
Ich habe aber nirgendwo einen Hinweis darauf gefunden, wie man ein Widget davor schützt, durch Verkleinern zu Verschwinden.

Natürlich kann ich das Hauptfenster mit .minsize festlegen, das soll sich aber dynamisch dem Inhalt anpassen können, ohne allzu großzügig zu starten.

Gibt es eine option von pack, um die Größe fest auf den Inhalt anzupassen?

Gego

Verfasst: Donnerstag 2. Oktober 2008, 10:43
von numerix
Hallo gego2, willkommen im Forum!

Zunächst meinen Glückwunsch zur Entscheidung für den pack()-Manager. Das ist m.E. in der Tat die beste Wahl. Auch komplexere Aufbauten bekommt man damit mittels verschachtelter Frames gut und übersichtlich hin.

Deine Frage ist mir nicht ganz klar: Um welche Art von Verkleinern geht es dir?
Meinst du das Verkleinern, das der Anwender z.B. mit der Maus am Fenster vornimmt? Oder geht es dir um ein anderes Verkleinern?

Vielleicht kannst du es an einem konkreten Beispiel erläutern: Was du getan hast und was nicht so klappt, wie du es gerne hättest.
Ein Codebeispiel schadet auch nicht.

Verfasst: Donnerstag 2. Oktober 2008, 14:07
von gego2
Hi numerix,

Herzlichen Dank für die Antort und die Glückwünsche.

es geht genau um die Veränderung des Anwenders.
Das ganze soll ein gui für den Anwender unserer SIP-Telefone werden - über astmanproxy mit einem asterisk verbunden.

Hier der Code (auf die GUI-Klasse) beschnitten, damit man was sieht:

Code: Alles auswählen

import Tkinter
import tkMessageBox


def login():
    pass
def logoff():
    pass
def dialout():
    pass
def sippeers():
    pass
def quit_main():
    Widgets.destroy()

output="SIP/101:\thello\nSIP/102:\tWorld"
class Gui(Tkinter.Tk):
    def __init__(self, master = None):
        Tkinter.Tk.__init__(self, master)
        self.title("Asterisk Dial Application")
        self.createwidgets()

    def createwidgets(self):
        self.minsize(200, 360)
##        self.maxsize(360, 480)
        self.topframe = Tkinter.Frame(self)
        self.topframe.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=Tkinter.NO)

        self.bottomframe = Tkinter.Frame(self)
        self.bottomframe.pack(side=Tkinter.BOTTOM, fill=Tkinter.BOTH, expand=Tkinter.NO)

        self.mainframe = Tkinter.Frame(self)
        self.mainframe.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=Tkinter.YES)

        self.MyMenu = Tkinter.Menu(self.mainframe)

        self.FileMenu = Tkinter.Menu(self.MyMenu, tearoff = 0)
        self.FileMenu.add_command(label="beenden", command=quit_main)

        self.PhoneMenu = Tkinter.Menu(self.MyMenu, tearoff = 0)
        self.PhoneMenu.add_command(label="logon", command=login)
        self.PhoneMenu.add_command(label="logoff", command=logoff)
        self.PhoneMenu.add_command(label="call", command=dialout)
        self.PhoneMenu.add_command(label="SIPpeers", command=sippeers)

        self.MyMenu.add_cascade(label="Datei", menu=self.FileMenu)
        self.MyMenu.add_cascade(label="Phone", menu=self.PhoneMenu)

        self.extenline = Tkinter.Entry(self.topframe, relief=Tkinter.SUNKEN)
        self.extenline.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=Tkinter.YES, padx=1, pady=1)

        self.clientdebug = Tkinter.Label(self.mainframe, bg="grey", relief=Tkinter.RAISED, width=30, anchor=Tkinter.NW, justify=Tkinter.LEFT)
        self.clientdebug.pack(fill=Tkinter.BOTH, expand=Tkinter.YES, side=Tkinter.TOP, padx=1, pady=1)
        self.clientdebug.pack_propagate()

        self.StatusAction = Tkinter.Label(self.bottomframe, height=1, relief=Tkinter.SUNKEN, text="Action", \
                                        bd=2, justify=Tkinter.LEFT, anchor=Tkinter.S)
        self.StatusAction.pack(fill=Tkinter.X, expand=Tkinter.YES, side=Tkinter.LEFT, padx=1, pady=1)


        self.StatusLogin = Tkinter.Label(self.bottomframe, height=1, relief=Tkinter.SUNKEN, text="Login", \
                                        bd=2, justify=Tkinter.LEFT, anchor=Tkinter.S)
        self.StatusLogin.pack(fill=Tkinter.X, expand=Tkinter.YES, side=Tkinter.LEFT, padx=1, pady=1)

        self.config(menu=self.MyMenu)
        self.protocol("WM_DELETE_WINDOW", quit_main)

        self.ClientAfter = self.after(500, Updateclient)

def Updateclient():
    Widgets.clientdebug['text']=output
    Widgets.ClientAfter = Widgets.after(500, Updateclient)

Widgets = Gui()
Widgets.mainloop()
durch das self.minsize wird hier ein Verkleinern durch den Anwender verhindert. Das Fenster ist aber zunächst viel zu groß. Ich kann es auf die Anzahl von momentan 23 angemeldeten SIP-Accounts begrenzen, möchte es aber flexibel halten.

Ich hoffe, das ist jetzt klarer und nicht etwa wirrer geworden (mal abgesehen vom Code)

P.S.: Wie sorge ich für Syntaxhighlighting, Zeilennummerierung und anständiges Aussehen ? Die code Tags allein tun's wohl nicht?

Verfasst: Donnerstag 2. Oktober 2008, 15:18
von Leonidas
gego2 hat geschrieben:P.S.: Wie sorge ich für Syntaxhighlighting, Zeilennummerierung und anständiges Aussehen ? Die code Tags allein tun's wohl nicht?
Steht in den Foren-FAQ.

Verfasst: Donnerstag 2. Oktober 2008, 15:30
von numerix
gego2 hat geschrieben:durch das self.minsize wird hier ein Verkleinern durch den Anwender verhindert. Das Fenster ist aber zunächst viel zu groß. Ich kann es auf die Anzahl von momentan 23 angemeldeten SIP-Accounts begrenzen, möchte es aber flexibel halten.
Ich verstehe das Problem nicht. :(

Auf meinem System (Linux/KDE 3.x) sieht die Anwendung direkt nach dem Start exakt so aus (Originalgröße):

Bild

Wo ist hier etwas "viel zu groß"?

Verfasst: Donnerstag 2. Oktober 2008, 15:52
von gego2
@Leonidas: Danke für den dezenten Hinweis

@numerix:
Auf meinem System (Linux/KDE 3.x) sieht die Anwendung direkt nach dem Start exakt so aus (Originalgröße)
Bei mir (sowohl Windows-XP als auch Ubuntu8.04/gnome2) sieht es so ähnlich aus.
Mein Problem: Die Anzeige ist zu groß bzw. unnötig groß für 2 Einträge - aber zu klein für 30.
Ich weiß vorher nicht, wie viele Einträge angezeigt werden müssen.

Verfasst: Donnerstag 2. Oktober 2008, 17:42
von numerix
Du brauchst den Aufruf von minsize() nur wegzulassen!
Dann wird das Anwendungsfenster gerade so groß wie für die Einträge nötig.

Und wenn du zur Laufzeit die Einträge änderst, passt sich die Größe an.

Gerade nochmal getestet - funktioniert.

Verfasst: Donnerstag 2. Oktober 2008, 18:43
von gego2
Danke, numerix. Das weiß ich, habe ich auch schon ausprobiert.

Um aber nochmal zu meiner Ausgangsfrage zurückzukehren: Wie verhindere ich dann (wenn sich die Größe dem Inhalt angepasst hat), dass der Anwender das Fenster wieder unter diese Größe zusammenschiebt?

Verfasst: Donnerstag 2. Oktober 2008, 20:07
von wuf
Hallo gego2

Ich habe dein Code-Snippet abgeändert ohne die 'Guidelines' einzuhalten da ich zu wenig Zeit habe das ganze neu zu schreiben. Den Einsatz von globalen Variablen habe ich desshalb auch missachtet du musst dich unbedingt mit den (PEP-8 Guidlines) befassen. Ich habe deine nicht mehr verwendeten Code-Zeilen auskommentiert. Die Reihenfolge von Frames verändert. Mit der linken Maustaste ins Label klicken erweitert eine Textzeile Klick bei Klick. Mit der rechten Maustaste ins Label klicken entfernt die Textzeile wieder.

Wichtige Änderungen sind:
a) self.resizable(0,0) (verhindert das Rahmenziehen des Hauptfensters mit der Maus)
b) Die Option 'width' aus 'self.clientdebug' entfernt
c) Diverse pack.Optionen angepasst

Hier der modifizierte Code:
[Code ausgelagert]

Wenn es mir recht ist kannst du 'minsize' bzw. 'maxsize' trotzdem einsetzen.

Gruss wuf :wink:

Verfasst: Donnerstag 2. Oktober 2008, 21:03
von numerix
gego2 hat geschrieben:Danke, numerix. Das weiß ich, habe ich auch schon ausprobiert.
Um aber nochmal zu meiner Ausgangsfrage zurückzukehren: Wie verhindere ich dann (wenn sich die Größe dem Inhalt angepasst hat), dass der Anwender das Fenster wieder unter diese Größe zusammenschiebt?
Sorry, das ist mir ganz durchgegangen. :oops:

Aber inzwischen hast du ja eine funktionierende Lösung von wuf.

Verfasst: Donnerstag 2. Oktober 2008, 21:09
von gego2
Hallo wuf,

erst einmal herzlichen Dank für Deine Mühe, Anmerkungen und Korrekturen.

Eigentlich befinde ich mich jetzt in einer Phase meines Lebens, in der ich mich von alten Konventionen und Bindungen befreien möchte, aber zugegebener Weise sollte man das nicht unbedingt auf das Verfassen von Code oder anderem Text übertragen. Die Guidelines hatte ich einmal, neben vielen Tutorien und Dokumentationen gelesen, deren Anwendung ist aber wohl über die Notwendigkeit funktionsfähige Programme zu schreiben in Vergessenheit geraten. MeA CuLpA - ich gelobe Besserung :oops:

Die .resizable Methode kannte ich noch gar nicht. Ist auch eine Lösung, aber was ich mir vorgestellt habe - jetzt hab' ich's - ist viel einfacher, als gedacht: Ich wusste nicht, dass die widgets nach der Reihenfolge ihres ge'pack'ed werdens verkleinert wurden. Ich wollte nur, dass das Entrywidget und das untere Label immer bestehen bleiben. Wenn ich diese also zuerst packe und ein .minsize mit hinreichend großem height Parameter setze, erreiche ich genau, was ich will.

http://pastebin.com/m44850025

Verfasst: Donnerstag 2. Oktober 2008, 21:16
von gego2
@numerix: Kein Problem, danke trotzdem
@Leonidas: gibt es hier auch eine Möglichkeit einen Thread (ich meine keinen Unterprozess) als gelöst zu markieren? Ich habe nichts in den FAQs dazu gefunden.

Verfasst: Freitag 3. Oktober 2008, 09:32
von Leonidas
gego2 hat geschrieben:@Leonidas: gibt es hier auch eine Möglichkeit einen Thread (ich meine keinen Unterprozess) als gelöst zu markieren? Ich habe nichts in den FAQs dazu gefunden.
Nö, das ist auch nicht erwünscht (wurde oft diskutiert und wir denken es ist so besser).