Übereinander Reihenfolge von Widgets

Fragen zu Tkinter.
Antworten
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Kann man herausbekommen, wie widgets, die sich gegenseitig verdecken oder teilverdecken, übereinander angeordnet sind?
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons

Kannst du das folgende Snippet einmal ausprobieren?:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from functools import partial

try:
    # Tkinter for Python 2.xx
    import Tkinter as tk
except ImportError:
    # Tkinter for Python 3.xx
    import tkinter as tk

APP_TITLE = "Lift lower frame to the top"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 300
APP_HEIGHT = 200

FRAMES = 5

class Application(tk.Frame):

    def __init__(self, master):
        self.master = master
        tk.Frame.__init__(self, master)
        
        for index in range(FRAMES):
            frame = tk.Frame(self, relief='raised', bd=1)
            frame.place(x=20, y=20, width=100, height=100)
            frame.name = "Frame: {}".format(index)
            if index == 0:
                frame['bg'] = 'green'

        frame['bg'] = 'red'
        
        for child in self.winfo_children():    
            print(child.winfo_class(), child.name, child)
        
        self.after(1000, self.lift_frame)
        
    def lift_frame(self):
        frame = self.winfo_children()[0]
        frame.lift()
        
def main():
    app_win = tk.Tk()
    app_win.title(APP_TITLE)
    app_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    app_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    
    app = Application(app_win).pack(fill='both', expand=True)
    
    app_win.mainloop()
 
 
if __name__ == '__main__':
    main()
Es liegen 5 Frames übereinander. Das oberste wird in rot angezeigt. Nach einer Sekunde wird das unterste grüne Frame nach oben gehievt.

Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

wuf hat geschrieben:Hi Alfons
Kannst du das folgende Snippet einmal ausprobieren?:
Hi wuf, das hatte ich mir auch fast gedacht, aber noch nicht ausprobiert. Wie findest Du dieses Snippet:

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk


# Application definition ============================

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        self.minsize(215, 320)
        # widget definitions ===================================
        self.red = Red(self,name='red')
        self.red.place(x='30', y='30')
        self.yellow = Yellow(self,name='yellow')
        self.yellow.place(x='60', y='60')
        self.green = Green(self,name='green')
        self.green.place(x='90', y='90')

        self.show_order()
        self.after(5000,self.lift_order)

    def show_order(self):
        for child in self.winfo_children():
            print(child)
        print('------------------------')

    def lift_order(self):
        self.winfo_children()[0].lift()
        self.show_order()
        self.after(5000,self.lift_order)

class Green(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        self.config(height=200, bg='lightgreen', relief='solid', width=100, bd=2)
        # widget definitions ===================================
        self.label = tk.Label(self,name='#3_label',bg='lightgreen', text='green')
        self.label.place(x='3', y='3')

class Red(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        self.config(height=200, bg='red', relief='solid', width=100, bd=2)
        # widget definitions ===================================
        self.label = tk.Label(self,name='#4_label',bg='red', text='red')
        self.label.place(x='3', y='3')

class Yellow(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        self.config(height=200, bg='yellow', relief='solid', width=100, bd=2)
        # widget definitions ===================================
        self.label = tk.Label(self,name='#5_label',bg='yellow', text='yellow')
        self.label.place(x='3', y='3')

if __name__ == '__main__':
    Application().mainloop()
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Man kann natürlich Widgets auch beliebig platzieren. Hier habe ich widgets eins runter und widgets eins rauf.

Zuerst kommt rot um eins hoch, dann grün eins runter, dann gelb eins rauf und nochmals eins rauf

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk


# Application definition ============================

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        self.minsize(215, 320)
        # widget definitions ===================================
        self.red = Red(self,name='red')
        self.red.place(x='30', y='30')
        self.yellow = Yellow(self,name='yellow')
        self.yellow.place(x='60', y='60')
        self.green = Green(self,name='green')
        self.green.place(x='90', y='90')


        self.exe_list = [None,self.red.up,self.green.down,self.yellow.up,self.yellow.up]
        self.exe_index = 0
        self.exec_list()

    def exec_list(self):
        if self.exe_index < len(self.exe_list):
            if self.exe_list[self.exe_index]:
                self.exe_list[self.exe_index]()
            self.exe_index += 1
            self.after(5000,self.exec_list)

class StackWidget:

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


    def up(self):
        children = self.master.winfo_children()
        count = len(self.master.winfo_children())
        index = children.index(self)
                          
        if count >= 2 and index != count-1:
            # rotate to second top
            while(self.master.winfo_children().index(self) != count-2):
                self.master.winfo_children()[0].lift()
            #now one up
            self.lift()
            
            #rotate until only one up
            while(self.master.winfo_children().index(self) != index+1):
                self.master.winfo_children()[0].lift()
                

    def down(self):
        children = self.master.winfo_children()
        count = len(self.master.winfo_children())
        index = children.index(self)
                          
        if count >= 2 and index:
            # rotate to second bottom

            while(self.master.winfo_children().index(self) != 1):
                self.master.winfo_children()[0].lift()
            #now one lower
            self.lower()
            
            # rotate until only one down
            while(self.master.winfo_children().index(self) != index-1):
                self.master.winfo_children()[0].lift()


class Green(tk.Frame,StackWidget):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        StackWidget.__init__(self,master)
        self.config(height=200, bg='lightgreen', relief='solid', width=100, bd=2)
        # widget definitions ===================================
        self.label = tk.Label(self,name='#3_label',bg='lightgreen', text='green')
        self.label.place(x='3', y='3')

class Red(tk.Frame,StackWidget):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        StackWidget.__init__(self,master)
        self.config(height=200, bg='red', relief='solid', width=100, bd=2)
        # widget definitions ===================================
        self.label = tk.Label(self,name='#4_label',bg='red', text='red')
        self.label.place(x='3', y='3')

class Yellow(tk.Frame,StackWidget):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        StackWidget.__init__(self,master)
        self.config(height=200, bg='yellow', relief='solid', width=100, bd=2)
        # widget definitions ===================================
        self.label = tk.Label(self,name='#5_label',bg='yellow', text='yellow')
        self.label.place(x='3', y='3')


if __name__ == '__main__':
    Application().mainloop()
Durch mehrmaliges down oder up kann man widgets dann auch beliebig im Stapel platzieren.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Alfons hat geschrieben:Hi wuf, das hatte ich mir auch fast gedacht, aber noch nicht ausprobiert. Wie findest Du dieses Snippet:
Freut mich dass dir mein Tipp mit dem w.winfo_children() geholfen hat.

Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

wuf hat geschrieben:
Alfons hat geschrieben:Hi wuf, das hatte ich mir auch fast gedacht, aber noch nicht ausprobiert. Wie findest Du dieses Snippet:
Freut mich dass dir mein Tipp mit dem w.winfo_children() geholfen hat.

Gruss wuf :wink:
Naja, nur ein wenig, denn ausprobiert hätte ich eh, ob meine Vermutung stimmt.

Aber Du kennst Dich ja hervorragend mit tkinter aus.
Früher hatte ich mich an effbot orientiert. Aber die vergessen oft Wesentliches, das ich dann auch nicht implementiert hatte.

Bei grid_rowconfigure und grid_columnconfigure wird 'uniform' nicht erwähnt.
Und beim PanedWindow wird sogar das Wichtigste vergessen, nämlich 'stretch'.
Das habe ich aber mittlerweile implementiert. Und 'uniform' soll eine bedeutende Rolle in meinem neuen Grid Konzept spielen. Ausprobiert habe ich aber da auch noch nchts, sondern nur darüber etwas aufgeschnappt.
Antworten