0

I'm not able to correctly align ttk widgets in the simple following application.

enter image description here

Code:

from tkinter import *
from tkinter import ttk

class App:
    def __init__(self, root):
        self.frames = []
        self.entries = []
        self.root = root
        self.root.title("Trajectories")
        
        self.FOPTIONS = ['A','B','C','D']
        self.LSOURCE = StringVar()
        self.LSOURCE.set(self.FOPTIONS[0])
        self.FINDX = IntVar()
        self.FLIST = ['0']
    
        ttk.Style().configure("TFrame", padding=6, relief="flat",background="#ccc")
        
        #F0 = ttk.Frame(self.root,padding=5)
        
        ttk.Button(self.root,text='Import').grid(row=0,column=0,padx=5,sticky="w")
        ttk.Combobox(self.root,textvariable=self.LSOURCE,values=self.FOPTIONS).grid(row=0,column=1,sticky="w") 
    
        F1 = ttk.Frame(self.root,padding=5)
        # Labels row
        ttk.Label(F1,text='Number').grid(row=0,column=0)
        ttk.Label(F1,text='File').grid(row=0,column=1)
        ttk.Label(F1,text='Alias').grid(row=0,column=2)
        ttk.Label(F1,text='Crop').grid(row=0,column=3)
        ttk.Label(F1,text='Show').grid(row=0,column=4)
        
        # Fields row
        ttk.Combobox(F1,textvariable=self.FINDX,values=self.FLIST,width=5).grid(row=1,column=0) # File
        ttk.Entry(F1,width=50).grid(row=1,column=1,padx=3,sticky='w')
        ttk.Entry(F1,width=15).grid(row=1,column=2,sticky='w') # Alias
        ttk.Checkbutton(F1).grid(row=1,column=3,sticky='we') # Crops
        ttk.Checkbutton(F1).grid(row=1,column=4,sticky='we')  # Show
        
        F1.grid(row=1,column=0,columnspan=2) 
        
        Button(self.root, text="Create",command=self.draw).grid(row=2,column=0,columnspan=2)
        
    def draw(self):
        print("Draw pressed")

root = Tk()
App(root)
root.mainloop()

The troubles are:

(i) with the first ttk.Combobox() and

(ii) Checkbuttons() under "Crop" and "Show" labels. I have tried many strategies but:

  • I haven't been able to place the ttk.Combobox() completely aligned to the left just close to the button "Import".

  • Checkbuttons() are without text and are not centered with respect to the labels in the row above.

The desirable situation should be something similar to the graphic below. Desirable situation

I have tried some variant encapsulating the first row into a frame but nothing changes. The second row with labels and the third row with the fields are encapsulated within a frame just to group a variable number of additional rows. the changes using sticky values did not produce any effect. Just I don't understand in this example how grid() is working in such a way and why the Combobox does not justify to the left("w") and why the "ew" does not center Checkbuttons() inside the cells.

If I try to grid the "Import" button as (row=0,column=0,sticky="w") an the ttk.Combobox().grid(row=0,column=0,sticky="w") as suggested in one of the comments I get:

enter image description here

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
user1259970
  • 333
  • 3
  • 14

2 Answers2

0

Finally the solution (although not 100% satified) has been to encapsulate the first row into a frame and using tk.Checkbutton() instead of ttk.Checkbutton() for the checkboxes.

F0 = ttk.Frame(self.root)       
ttk.Button(F0,text='Import').grid(row=0,column=0,padx=5,sticky="w")
ttk.Combobox(F0,.....).grid(row=0,column=1,sticky="w") 
F0.grid(row=0,column=0,sticky="w")

and using tk instead of tkk widgets for Checkbutton

# ttk.Checkbutton(F1).grid(row=1,column=3,sticky='we')
tk.Checkbutton(F1).grid(row=1,column=3,sticky='we')

In my opinion is very strange that ttk does not obey "sticky" behaviour correctly (maybe a bug ?).

user1259970
  • 333
  • 3
  • 14
  • It's not a bug. I'm not 100% sure what you're referring to, but the grid geometry manager has been around for a couple decades, if there was a bug in it someone would have found it years ago. – Bryan Oakley Dec 22 '20 at 16:52
  • Probably you are true but just try the difference between the tk and ttk versions as the case I have reported here and you will see that they respond differently, what does not mean that all ttk widgets have this problem. In my opinion is not a matter of the grid() but the way ttk.Checkbutton() implements it. – user1259970 Dec 22 '20 at 17:02
  • The `ttk.Checkbutton` doesn't have a separate implementation of `grid` - all widgets share the same implementation. – Bryan Oakley Dec 22 '20 at 17:05
  • Please, any hint how to suppress the label space through the style layout ? I did not find how to do that ? – user1259970 Dec 22 '20 at 17:09
0

The reason that the combobox isn't immediately to the right of the import button is because column 0 is wider than you think. You can see that the combobox is right up against the button if you temporarily comment out F1.grid(row=1,column=0,columnspan=2)

It is that wide because you put F1 in column 0 and have it span two columns, so by definition column 0 and column 1 together must be as wide as F1.

One simple solution is to have a third column that is empty, and have it take up the extra space. Do that by having F1 span three columns, and giving a non-zero weight to the third column. That column will then get all extra space, so columns 0 and 1 will be only as large as the largest item in that column.

The problem with the checkbuttons is simply that there's space for the label whether you have a label or not, so the actual checkbox is offset to the left. Since you are using a ttk Checkbutton, you can completely remove the label from the style layout for that widget if you want the checkbutton to be centered.

It should look something like this:

ttk.Style().layout("CustomCheckbutton", [('Checkbutton.button', {'sticky': 'nswe'})])
...
ttk.Checkbutton(F1, style="CustomCheckbutton").grid(row=1,column=3) # Crops
ttk.Checkbutton(F1, style="CustomCheckbutton").grid(row=1,column=4)  # Show
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685