Widgets mit pack vor "zusammenschieben" schützen?

Fragen zu Tkinter.
Antworten
gego2
User
Beiträge: 6
Registriert: Samstag 27. Oktober 2007, 14:35

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
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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.
gego2
User
Beiträge: 6
Registriert: Samstag 27. Oktober 2007, 14:35

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?
Zuletzt geändert von gego2 am Donnerstag 2. Oktober 2008, 15:52, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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ß"?
gego2
User
Beiträge: 6
Registriert: Samstag 27. Oktober 2007, 14:35

@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.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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.
gego2
User
Beiträge: 6
Registriert: Samstag 27. Oktober 2007, 14:35

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?
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

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:
Take it easy Mates!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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.
gego2
User
Beiträge: 6
Registriert: Samstag 27. Oktober 2007, 14:35

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
gego2
User
Beiträge: 6
Registriert: Samstag 27. Oktober 2007, 14:35

@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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten