Frame - Originalgroesse soll beibehalten werden

Fragen zu Tkinter.
Antworten
Benutzeravatar
ts7343
User
Beiträge: 69
Registriert: Mittwoch 5. Mai 2010, 13:48

Hallo,

gibt es eine Möglichkeit, dass man einen Frame derart vorkonfiguriert, dass er ueber den gesamten
Zeitraum die gleiche Grösse behält?

Die Idee ist eigentlich, dass man fuer bestimmte Optionen einen Leerraum läßt, der sich erst später füllt.

Zur Zeit mache ich mächtige Verrenkungen mit dummy-Labels als Platzhalter, aber das kann es eigentlich nicht sein, oder?
Im Quelltext sind die Platzhalter die beiden dummy_label_0x um den frame fuer das Advanced Menu: frame_advanced
ungefaehr auf die Groesse zu bringen.

Was ich eigentlich bräuchte wäre quasi:
1) Zeige alle Optionmenus beim Start
2) Berechne dir eine definierte Framegroesse
3) loesche die Optionmenues, aber lass den Frame genauso gross, wie er vorher war,

Der Grund ist, dass sich sonst auch andere Widgets im Original-tool komplett verschieben, wenn der Frame andauernd
die Groesse aendert.

Hat da jemand einen Trick oder eine Idee?

Thanx

Code: Alles auswählen

#!/usr/bin/env python

import Tkinter as tk
import string, re, os, sys, subprocess, datetime

class AppFunctions(tk.LabelFrame):

   def __init__(self, master): 
   
      self.extend_flag = 0

      tk.LabelFrame.__init__(self, master)    
#     definition
      self.option_01_list = ["01_01","01_02","01_03"]
      self.option_01_var  = tk.StringVar(self)
      self.option_01_var.set(self.option_01_list[0])
      self.option_01      = tk.OptionMenu(self,self.option_01_var, *self.option_01_list)

      frame_advanced      = tk.Frame(self)      
      button_advanced     = tk.Button(frame_advanced, command=self.extend_or_reduce_menu)

      self.dummy_label_01 = tk.Label(frame_advanced)
      self.dummy_label_02 = tk.Label(frame_advanced)

      self.option_04_list = ["04_01","04_02"]
      self.option_04_var  = tk.StringVar(self)
      self.option_04_var.set(self.option_04_list[0])
      self.option_04      = tk.OptionMenu(frame_advanced,self.option_04_var, *self.option_04_list)
      self.option_05_list = ["05_01","05_02"]
      self.option_05_var  = tk.StringVar(self)
      self.option_05_var.set(self.option_05_list[0])
      self.option_05      = tk.OptionMenu(frame_advanced,self.option_05_var, *self.option_05_list)
      
#     position
      self.option_01.grid( row=0, column=0,pady=4)                  
      frame_advanced.grid( row=2, column=0, columnspan=2)      
      button_advanced.grid(row=0, column=0) 
      self.dummy_label_01.grid(row=1, column=0, pady=5)
      self.dummy_label_02.grid(row=2, column=0, pady=5)

      self.grid( row=0, column=0, padx=2, pady=2, sticky="N"+"S"+"E"+"W") 
      
#     configuration
      self.configure(text="submitting",bg="#888888",relief="ridge",borderwidth=2)
      self.option_01.configure(width=30,bg="#888888",justify= "left")

      frame_advanced.configure(bg="#888888",relief="ridge",borderwidth=2)
      button_advanced.configure(bg="#666666",text="   Advanced ...   ")

      self.dummy_label_01.configure(text="                   ", bg="#888888")
      self.dummy_label_02.configure(text="                   ", bg="#888888")
      
      self.option_04.configure(width=15,bg="#888888",justify= "left")
      self.option_05.configure(width=15,bg="#888888",justify= "left")


   def extend_or_reduce_menu(self):
      changed_flag = 0
      if (self.extend_flag == 0):
         print self.extend_flag
         self.option_04.grid(row=1, column=0)
         self.option_05.grid(row=2, column=0)
         self.extend_flag = 1         
         changed_flag     = 1
         
      if ( (self.extend_flag == 1) and (changed_flag == 0) ):
         print self.extend_flag            
         self.option_04.grid_remove()   
         self.option_05.grid_remove()
         self.extend_flag = 0   

if __name__ == "__main__":
   root = tk.Tk()
   root.geometry("400x300")
   root.config(background="#888888")
   root.option_add('*font',("courier",8,"bold"))
   root.title("submitting")
   display = AppFunctions(root)
   root.mainloop()
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Du hast ein paar Wünsche :D.

Feste Größen behältst du mit

Code: Alles auswählen

frame.propagate(False)
bei.

Zu dem Rest sag ich erstmal nichts. :roll:
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
ts7343
User
Beiträge: 69
Registriert: Mittwoch 5. Mai 2010, 13:48

Au Backe, so schlimm?

Aber das "propagate" probier ich mal,
mal schauen, ob das klappt,
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Naja, deine Idee ist mir zwar Rätselhaft, aber wenn es geht nur zu. :D

Aber deine Syntax solltest du echt nochmal überarbeiten, vorallem die leerzeichen.
Ich verstehe ja noch, das du bei den Zuweisungen Leerzeichen lässt, um auf die selbe Spalte zu kommen wie darüber, um eine bessere Übersicht zu bekommen.
Dennoch sind einige Leerzeichen echt deplatziert.

Was sollen die Klammern bei if ?

Und deine Namensgebung ist wie eh und je, die könnten ruhig ein wenig mehr aussagen :D

Aber löse erstmal dein Problem, dann kannst du das immernoch überarbeiten :)
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
ts7343
User
Beiträge: 69
Registriert: Mittwoch 5. Mai 2010, 13:48

Naja, die Idee ist eigentlich, dass neben den Optionen ein Textwidget steht, je nach Einschalten/Ausschalten
der Optionen bewegt es sich hin und her, da dachte ich mir, ein fixer Frame koennte da helfen.

Bei if die Klammern, das ist fuer mich besser lesbar, weil der Ausdruck komplett besser sichtbar ist,

Die Namensgebung, ja, da muesste ich nochmal ran, aber fuer so ein Forum-Beispiel erst mal ok, oder?

Nun hab ich ein propagate gesetzt, aber nun seh ich es gar nicht mehr. Meine Idee war dabei:
1. Optionmenues setzen
2. propagate anschalten
3. Optionmenues wieder loeschen,

Code: Alles auswählen

#     !!! here the propagate command is set !!!
      self.option_04.grid(row=1, column=0)
      self.option_05.grid(row=2, column=0)
      frame_advanced.propagate(False)
      self.option_04.grid_remove()   
      self.option_05.grid_remove()
hier der gesamte Code:

Code: Alles auswählen

#!/usr/bin/env python

import Tkinter as tk
import string, re, os, sys, subprocess, datetime

class AppFunctions(tk.LabelFrame):

   def __init__(self, master): 
   
      self.extend_flag = 0

      tk.LabelFrame.__init__(self, master)    
#     definition
      self.option_01_list = ["01_01","01_02","01_03"]
      self.option_01_var  = tk.StringVar(self)
      self.option_01_var.set(self.option_01_list[0])
      self.option_01      = tk.OptionMenu(self,self.option_01_var, *self.option_01_list)
#     definition - advanced part
      frame_advanced      = tk.Frame(self)      
      button_advanced     = tk.Button(frame_advanced, command=self.extend_or_reduce_menu)
      self.option_04_list = ["04_01","04_02"]
      self.option_04_var  = tk.StringVar(self)
      self.option_04_var.set(self.option_04_list[0])
      self.option_04      = tk.OptionMenu(frame_advanced,self.option_04_var, *self.option_04_list)
      self.option_05_list = ["05_01","05_02"]
      self.option_05_var  = tk.StringVar(self)
      self.option_05_var.set(self.option_05_list[0])
      self.option_05      = tk.OptionMenu(frame_advanced,self.option_05_var, *self.option_05_list)      
#     position
      self.grid(row=0, column=0, padx=2, pady=2, sticky="N"+"S"+"E"+"W") 
      self.option_01.grid(row=0, column=0,pady=4) 
#     position - advanced part                       
      frame_advanced.grid(row=1, column=0, columnspan=2)      
      button_advanced.grid(row=0, column=0) 
#
#     !!! here the propagate command is set !!!
      self.option_04.grid(row=1, column=0)
      self.option_05.grid(row=2, column=0)
      frame_advanced.propagate(False)
      self.option_04.grid_remove()   
      self.option_05.grid_remove()
#
#     configuration
      self.configure(text="submitting",bg="#888888",relief="ridge",borderwidth=2)
      self.option_01.configure(width=30,bg="#888888",justify= "left")
#     configuration - advanced part
      frame_advanced.configure(bg="#888888",relief="ridge",borderwidth=2)
      button_advanced.configure(bg="#666666",text="Advanced ...")
      self.option_04.configure(width=15,bg="#888888",justify= "left")
      self.option_05.configure(width=15,bg="#888888",justify= "left")

   def extend_or_reduce_menu(self):
      changed_flag = 0
      
      if (self.extend_flag == 0):
         self.option_04.grid(row=1, column=0)
         self.option_05.grid(row=2, column=0)
         self.extend_flag = 1         
         changed_flag     = 1
         
      if ( (self.extend_flag == 1) and (changed_flag == 0) ):
         self.option_04.grid_remove()   
         self.option_05.grid_remove()
         self.extend_flag = 0   

if __name__ == "__main__":
   root = tk.Tk()
   root.geometry("400x300")
   root.config(background="#888888")
   root.option_add('*font',("courier",8,"bold"))
   root.title("submitting")
   display = AppFunctions(root)
   root.mainloop()

Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Du musst dem LabelFrame eine feste Größe zuordnen, ansonsten ist diese 0.
Es gibt immer eine relative und eine feste Größe bei den Widgets,
die festen Größen, sind aber dehnbar, nimmst du die dehnbarkeit mit propagate heraus, so gilt die feste Größe.
Diese ist aber bei deinem LabelFrame 0, weil du nur das ToplevelWidget mit geometrie eine Größe zugeordnet hast.

Einfache Lösung, du setzt die width und die height Option bei deinem LabelFrame.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
ts7343
User
Beiträge: 69
Registriert: Mittwoch 5. Mai 2010, 13:48

Nun hab ich den Frame mit width/heigt ueber configure gesetzt, aber er bewegt sich trotz
anschliessendem propagate:
self.frame_advanced.configure(bg="#888888",relief="ridge",borderwidth=2, width=200, height=300)
self.frame_advanced.propagate(False)

Ich hab auch versucht, erst die Widgets zu setzen und in einer separaten Funktion das propagate aufzurufen,
damit der Frame dort eine feste Groesse hat, aber auch das geht nicht,

Hattu zufaellig noch eine Idee? Oder einen anderen Ansatz?

Hier der Code:

Code: Alles auswählen

#!/usr/bin/env python

import Tkinter as tk

class AppFunctions(tk.LabelFrame):

   def __init__(self, master): 
   
      self.extend_flag = 1

      tk.LabelFrame.__init__(self, master)    
#     definition
      self.option_01_list = ["01_01","01_02","01_03"]
      self.option_01_var  = tk.StringVar(self)
      self.option_01_var.set(self.option_01_list[0])
      self.option_01      = tk.OptionMenu(self,self.option_01_var, *self.option_01_list)
#     definition - advanced part
      self.frame_advanced      = tk.Frame(self)      
      button_advanced     = tk.Button(self.frame_advanced, command=self.extend_or_reduce_menu)
      self.option_04_list = ["04_01","04_02"]
      self.option_04_var  = tk.StringVar(self)
      self.option_04_var.set(self.option_04_list[0])
      self.option_04      = tk.OptionMenu(self.frame_advanced,self.option_04_var, *self.option_04_list)
#     position
      self.grid(row=0, column=0, padx=2, pady=2, sticky="N"+"S"+"E"+"W") 
      self.option_01.grid(row=0, column=0,pady=4) 
#     position - advanced part                       
      self.frame_advanced.grid(row=1, column=0, columnspan=2)      
      button_advanced.grid(row=0, column=0) 
      self.option_04.grid(row=1, column=0)
#     configuration
      self.configure(text="submitting",bg="#888888",relief="ridge",borderwidth=2)
      self.propagate(False)
      self.option_01.configure(width=30,bg="#888888",justify= "left")
#     configuration - advanced part
      self.frame_advanced.configure(bg="#888888",relief="ridge",borderwidth=2, width=200, height=300)
      self.frame_advanced.propagate(False)
      
      button_advanced.configure(bg="#666666",text="Advanced ...")
      self.option_04.configure(width=15,bg="#888888",justify= "left")
      
   def extend_or_reduce_menu(self):
      changed_flag = 0      
      if (self.extend_flag == 0):
         self.option_04.grid(row=1, column=0)
         self.extend_flag = 1         
         changed_flag     = 1         
      if ( (self.extend_flag == 1) and (changed_flag == 0) ):
         self.option_04.grid_remove()   
         self.extend_flag = 0   

if __name__ == "__main__":
   root = tk.Tk()
   root.geometry("400x300")
   root.config(background="#888888")
   root.option_add('*font',("courier",8,"bold"))
   root.title("submitting")
   display = AppFunctions(root)
   root.mainloop()
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Sorry, hatte es in deinem Code über sehen, das du das zusätzlich noch auf einen Frame unter dem eigentlichen Frame machen willst.
Dafür gibt es grid_propagate() oder pack_propagate(). - width, height gelten trotzdem.

Aber solangsam glaube ich das du einfach nur nach einer invisible Methode suchst, oder ?
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
ts7343
User
Beiträge: 69
Registriert: Mittwoch 5. Mai 2010, 13:48

yesly,
grundsaetzlich brauch ich eigentlich nur eine Funktion, die auf den Advanced Button reagiert,
alle OptionMenues visible oder unvisible macht, und den jeweiligen Text im Button aendert,
je nachdem ob die Widget visible sind oder nicht,

ich kenn das von einer Hochsprache die heisst: PCL (Patran Command Language),
dort gibt es einfach ein "show" und ein "hide" und man kann seine Widgets einfach positionieren
und ein "hide" draufmachen und fertig ist die Laube, so werden dutzende Menues uebereinander gepackt
und ueber Optionmenues dann halt gezeigt oder nicht.

die einfache Fix-Loesung mit width und height funktioniert im Zusammenhang mit grid_propagate()! Also zur Not komm ich damit zurecht,
aber so richtig gut finde ich die eigentlich nicht, da man ja immer bedenken muss,
dass auf verschiedenen Rechnern oder OS die Pixelgroessen ausreichen, oder zu gross oder zu klein
sein koennten, oder?

Gibt es etwa eine Invisible/Visible Methode, die die Positions sich merkt und den Frame so laesst, wie er ist?
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Leider nein, nur für das Toplevel Widget. :cry:

Aber du könntest, wenn es wirklich so statisch sein soll genauso gut place nutzen, da bewegen sich die Elemente nicht einen Millimeter.
ts7343 hat geschrieben:die einfache Fix-Loesung mit width und height funktioniert im Zusammenhang mit grid_propagate()! Also zur Not komm ich damit zurecht,
aber so richtig gut finde ich die eigentlich nicht, da man ja immer bedenken muss,
dass auf verschiedenen Rechnern oder OS die Pixelgroessen ausreichen, oder zu gross oder zu klein
sein koennten, oder?
Daran wirst du nie vorbeikommen, also --> Scrollbars.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
ts7343
User
Beiträge: 69
Registriert: Mittwoch 5. Mai 2010, 13:48

Xynon1 hat geschrieben: Daran wirst du nie vorbeikommen, also --> Scrollbars.
Oh man, auch das noch,

aber da hab ich neulich was gutes zu gesehen in dem Thread: "Maximale Anzahl an Elementen in einem Grid?"

Mal kieken ob ich mir da etwas abgucken kann ...
Antworten