Home > Software engineering >  How to arrange multiple items in the same row after using columnconfigure (global columnconfigure?)
How to arrange multiple items in the same row after using columnconfigure (global columnconfigure?)

Time:12-30

Coming off of this question, everything works great as-is. However, in my own program, I intended to use multiple columns, and the moment I do so, things get dicey. I am trying to center multiple items in the same row, but it doesn't really work out. The code looks like this:

from tkinter import *

    class Column_example(Frame):
        def __init__(self):
    #initializing the frame itself
            Frame.__init__(self)
            self.place(relx = 0.5, relwidth = 1, anchor='n')
            self.columnconfigure(0, weight=1)
            self.columnconfigure(1, weight=1)
    #initializing some stuff
            self.data_list = []
            self.data = 0
    #button locations                 
            self.button = Button(self, text = "Go", command = self.go)
            self.button.grid(row = 0, column = 0)
            self.redo = Button(self, text = "Erase", command = self.erase)
            self.redo.grid(row = 0, column = 1)
    #commands
        def go(self):
            for self.data in range(1, 20000, 100):
                self.data_list.append(self.data)
                
            self.data = Label(self, text = self.data_list, wraplength = self.master.winfo_width(), font = 'arial 30')
            self.data.grid(row = 2, column = 0, columnspan = 100)
            self.data.bind('<Configure>', self.rewrap)
        def erase(self):
            self.data.destroy()
            self.data_list.clear()
        def rewrap(self, event):
            self.data.config(wraplength = self.master.winfo_width())
            
    frame01 = Column_example()
    frame01.mainloop()

I am aware that Erase throws an error if Go is used twice beforehand, but this is irrelevant as this code is merely an example case of my actual problem. Before adding self.columnconfigure(1, weight=1), the Go button was essentially centered, but the Erase button was pushed to the far right of the screen. After adding it, they are equidistant from each other and both sides. Now, that is to be expected for equally sized columns, and I already had a solution that worked before.

By setting columnspan of the largest entry to a high number, I could then place other items relative to it with precision. In this example, the screen-filling data has columnspan = 100. I can then place things in columns equal to their percentage distance across the screen. Setting Go to column 49, and Erase to column 51 achieved exactly what I wanted, with them both near center (after the data was written, but in my actual program, the data is written before the screen is loaded, so it looks normal). But it stopped working after I did columnconfigure. Now setting it to that places them both at the far right of the screen. I need columnconfigure to maintain the dynamic text wrapping as seen in my previous question, so I'm wondering how to work around this. One possible solution is to manually configure all 100 columns, but surely there is a better way... or at least a way to do that that doesn't require 100 lines of code.

CodePudding user response:

If you want the the two buttons to be centered, then I recommend you use a maximum of two columns. Make them the same width via the uniform option, and have the buttons hug the right and left edges of the column.

self.button.grid(row = 0, column = 0, sticky="e")
self.redo.grid(row = 0, column = 1, sticky="w")
...
def go(self):
    ...
    self.data.grid(row = 2, column = 0, columnspan = 2, sticky="ew")
    ...

Another approach would be to use three columns, with the middle column reserved for the buttons. Put the buttons in a frame, and put the frame in that column. Then, configure columns 0 and 2 of self to have a non-zero weight, and have the long label span all three columns. The end result is that the middle column will remain centered with just the two buttons.

The advantage to this is that you can add as many buttons as you want to the button frame and the group of buttons as a whole will remain centered.

  • Related