Home > database >  Mix vertical and horizontal PanedWindow() on tkinter and moves sashes together
Mix vertical and horizontal PanedWindow() on tkinter and moves sashes together

Time:11-17

I just started using tkinter and I am feeling good about it, but I am now facing an issue and can't seem to find anything about it. I am currently trying to create this shape with PanedWindow():

########|#######
#       |      #
--------|-------
#       |      #
########|#######

I currently have a code that does create this shape and I can resize the pane windows (- & |). The problem is that I need these (|) to move together like these (-). If that wasn't clear, I am trying to move the center dividers together. Currently, they are like so :

###|############
#  |           #
----------------
#           |  #
############|###

If this is still not clear, try it out! I put the code below. As you can see, you can move the vertical lines together, but not the horizontal ones. I know that the reason is that there are 2 independent pane windows inside of one main pane window, so they act independently. I still don't know how I could link them together!

from tkinter import *

master = Tk()

master.geometry("400x400")

# Main Pane
main_panel = PanedWindow(orient=VERTICAL, bd=2, relief="solid", bg="black")
main_panel.pack(fill="both", expand=1)


# Sub Panes

##############################################################################

top_left = PanedWindow(main_panel, bd=1, relief="solid", bg="black")
top_left.pack(fill="both", expand=1)

left_label = Label(top_left, text= "Left-top")
top_left.add(left_label)

top_right = PanedWindow(top_left, orient=VERTICAL, bd=4)
top_left.add(top_right)

right_label = Label(top_left, text= "Right-top")
top_right.add(right_label)


#############################################################



bottom_left = PanedWindow(main_panel, bd=1, relief="solid", bg="black")
bottom_left.pack(fill="both", expand=1)

left_label = Label(bottom_left, text= "Left-bottom")
bottom_left.add(left_label)

bottom_right = PanedWindow(bottom_left, orient=VERTICAL, bd=4)
bottom_left.add(bottom_right)

right_label = Label(bottom_left, text= "Right-bottom")
bottom_right.add(right_label)


main_panel.add(top_left)
main_panel.add(bottom_left)

mainloop()

CodePudding user response:

I tried to find a most general solution to this problem, as I thought you may want to add more paned windows to main_panel. Anyway this can be achieved with fewer lines of code, but for demonstration I did it more steps than needed.

References:

import tkinter as tk #dont use wildcard imports



def onB1Motion(event):#bindings are executed with event objects
    widget = event.widget #get widget/paned window of event
    x,y = event.x,event.y #get x and y coord of event
    data = widget.identify(x,y) #paned window identify
    if data != '': #identify returns empty string if child window
        idx = data[0] #get sash index
        orient = event.widget['orient'] #check for orientation of paned window
        for child in widget.master.winfo_children(): #get all children of master
            if isinstance(child,tk.PanedWindow): #if children is paned window do..
                if child['orient'] == orient: #if child paned window is same orient as event paned do..
                    child.sash_place(idx,x,y) #places the sash with same index on same position

LABEL_WIDTH = 10 #simulate natural size by label width

master = tk.Tk()
master.geometry("400x400")
# Main Pane
main_panel = tk.PanedWindow(orient=tk.VERTICAL, bd=2, relief="solid", bg="black")
main_panel.pack(fill="both", expand=1)
# Sub Panes
##############################################################################
top_left = tk.PanedWindow(main_panel, bd=1, relief="solid", bg="black")
top_left.pack(fill="both", expand=1)

left_label = tk.Label(top_left,width=LABEL_WIDTH, text= "Left-top")
top_left.add(left_label)

top_right = tk.PanedWindow(top_left, orient=tk.VERTICAL, bd=4)
top_left.add(top_right)

right_label = tk.Label(top_left,width=LABEL_WIDTH, text= "Right-top")
top_right.add(right_label)
##############################################################################
bottom_left = tk.PanedWindow(main_panel, bd=1, relief="solid", bg="black")
bottom_left.pack(fill="both", expand=1)

left_label = tk.Label(bottom_left,width=LABEL_WIDTH, text= "Left-bottom")
bottom_left.add(left_label)

bottom_right = tk.PanedWindow(bottom_left, orient=tk.VERTICAL, bd=4)
bottom_left.add(bottom_right)

right_label = tk.Label(bottom_left,width=LABEL_WIDTH, text= "Right-bottom")
bottom_right.add(right_label)
##############################################################################
main_panel.add(top_left)
main_panel.add(bottom_left)

##binding class/all paned windows to execute command {onB1Motion} by {B1-Motion}
## USE ADD=  TO DONT OVERWRITE THE STANDARD ONE
master.bind_class(main_panel.winfo_class(),'<Button1-Motion>',onB1Motion,add=' ')

master.mainloop()
  • Related