Home > other >  Python: tkinter - how to dynamically generate grids?
Python: tkinter - how to dynamically generate grids?

Time:02-17

My application should look as follows:

  • If I click in BasicWindow at Button "Left" and click in NewWindow (should be some widget in seperate class) at Button "apply", in a cell of some grid (4 columns) below of Button "Left" the word hello should appear. If I repeat that n times, new words "Hello" should arranged in the grid below of the "Left" button n times.

  • If I click in BasicWindow at Button "Right" and click in NewWindow at Button "apply", in a cell of some grid (4 columns) below of Button "Left" the word hello should appear. If I repeat that n times, new words "Hello" should arranged in the grid below of the "Right" button n times.

This graphic illustrates, what the program should do: enter image description here

I just tried to solve that with following code:

from tkinter import *

class NewWindow(Toplevel):
    def __init__(self, master = None, apply=None):
        super().__init__(master = master)
        self.title('NewWindow')
        self.master = master
        self.words = 'Hello'

 
        self.bt1 = Button(self, text="apply", command=self.bt_press)
        self.bt1.grid(column=0, row=0)
        self.apply = apply
    def bt_press(self):
        self.apply(self.words)
        self.destroy()

window = Tk()

def new_Editor(key):
    def make_label1(lbl_txt):
        lbl = Label(window, text=lbl_txt)
        lbl.grid(column=0,row=2)
    def make_label2(lbl_txt):
        lbl = Label(window, text=lbl_txt)
        lbl.grid(column=2,row=2)

    if key == 1:
        a = NewWindow(window, make_label1)
    else:
        a = NewWindow(window, make_label1)

window.title("BasicWindow")

window.basic_bt_l = Button(window, text="Left", command=lambda: new_Editor(1))
window.basic_bt_l.grid(column=0, row=0, columnspan=2)


window.basic_bt_r = Button(window, text="Right", command=lambda: new_Editor(2))
window.basic_bt_r.grid(column=1, row=0)

window.mainloop()

My Programm looks like this:

enter image description here

For some reason the two buttons are not very good arranged and the format of the output isn't very good. How can I just define some well formatet grid between Left and Right button and two grids below of Left/Right button with the properties I descriped above?

CodePudding user response:

You've specified columnspan=2 when adding root.basic_bt_l to the window, so it will occupy columns 0 and 1. You then try to put root.basic_bt_r in column 1, which will overlap the first button.

Sometimes these mistakes are easier to see if you group your grid statements together. Notice how the columnspan sticks out like a sore thumb here, and makes it easier to visualize the layout

root.basic_bt_l.grid(column=0, row=0, columnspan=2)
root.basic_bt_r.grid(column=1, row=0)

You need to remove columnspan=2 so that the buttons don't overlap.

As for adding new words on new rows, you will need to calculate which row to place the new label. In this specific case, since you are stacking the labels vertically and never remove them from the middle, you can use the grid_slaves method to tell you how many labels there are. You can add one to that number to get the first empty row for that column. You could also just keep a counter of how many labels you've added for each column.

You also need to make sure that you call make_label2 - you are calling make_label1 in both conditions of your if statement.

def new_Editor(key):
    def make_label1(lbl_txt):
        print("root.grid_slaves(0):", root.grid_slaves(column=0))
        row = len(root.grid_slaves(column=0)) 1
        lbl = Label(root, text=lbl_txt)
        lbl.grid(row=row, column=0)
    def make_label2(lbl_txt):
        print("root.grid_slaves(1):", root.grid_slaves(column=1))
        row = len(root.grid_slaves(column=1)) 1
        lbl = Label(root, text=lbl_txt)
        lbl.grid(row=row, column=1)

    if key == 1:
        a = NewWindow(root, make_label1)
    else:
        a = NewWindow(root, make_label2)

  • Related