Управление шириной столбца tkinter

Я просмотрел документацию по rowconfugre и columnconfigure и просто не совсем понимаю, как заставить ее работать правильно. С помощью следующего кода, как я могу получить поле ввода «src_entry» непосредственно против контрольной кнопки «src», независимо от того, какой другой виджет находится в столбце 1? По сути, мне нужно, чтобы размер столбца соответствовал ширине любого виджета, находящегося в этом пространстве сетки.

Спасибо,

from tkinter import *



class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent, background="white")
        self.parent = parent
        self.parent.title("TCPDUMP Creator")
        self.centerWindow()
        self.pack(fill=BOTH, expand=1)

        menubar = Menu(self.parent)
        self.parent.config(menu=menubar)
        fileMenu = Menu(menubar)
        fileMenu.add_command(label="Exit", command=self.quit)
        menubar.add_cascade(label="File", menu=fileMenu)
        self.columnconfigure(2, weight=5)

        int_lbl = Label(self, text="Interface")
        int_lbl.grid(row=1, column=0, sticky=W+E)
        self.int_entry = Entry(self, width=15)
        self.int_entry.grid(row=1, column=1)

        self.anyInt = BooleanVar()
        Checkbutton(self, text="Any", variable = self.anyInt).grid(row=1, column=2)

        int_lbl = Label(self, text="")
        int_lbl.grid(row=2, column=0, columnspan=99, sticky=W+E)

        self.notSrc = BooleanVar()
        Checkbutton(self, text = "Not--", variable = self.notSrc).grid(row=3, column=0, sticky=W+E)

        self.srcIP = BooleanVar()
        Checkbutton(self, text="Src", variable = self.srcIP).grid(row=3, column=1)

        src_entry = Entry(self, width=15)
        src_entry.grid(row=3, column=2)

        self.AndOr = StringVar()
        self.AndOr.set(None)

        Radiobutton(self, text = "And", variable = self.AndOr, value = "And").grid(row=3, column=3, pady=5, padx=2, sticky=E)
        Radiobutton(self, text = "Or", variable = self.AndOr, value = "Or").grid(row=3, column=4, pady=5, padx=10, sticky=W)

        self.notDst = BooleanVar()
        Checkbutton(self, text = "Not--", variable = self.notDst).grid(row=3, column=5, sticky=W+E)

        self.dstIP = BooleanVar()
        Checkbutton(self, text="Dst", variable = self.dstIP).grid(row=3,column=6, sticky=E, padx=0)

        dst_entry = Entry(self, width=15)
        dst_entry.grid(row=3, column=7)

        int_lbl = Label(self, text="")
        int_lbl.grid(row=4, column=0, columnspan=99, sticky=W+E)


        self.srcordst = StringVar()
        self.srcordst.set(None)

        Radiobutton(self, text = "And", variable = self.srcordst, value = "And").grid(row=4, column=1, pady=5, padx=2, sticky=E)
        Radiobutton(self, text = "Or", variable = self.srcordst, value = "Or").grid(row=4, column=2, pady=5, padx=10, sticky=W)


    def centerWindow(self):
        w = 600
        h = 300
        sw = self.parent.winfo_screenwidth()
        sh = self.parent.winfo_screenheight()
        x = (sw - w)/2
        y = (sh - h)/2.7
        self.parent.geometry("%dx%d+%d+%d" % (w, h, x, y))




def main():
    root = Tk()
    app = Example(root)
    root.mainloop()

if __name__ == '__main__':
    main()

person Clyde    schedule 29.03.2017    source источник


Ответы (1)


Лучший способ сделать макеты — разбить пользовательский интерфейс на разделы, а затем разместить каждый раздел отдельно. Причина, по которой у вас возникают трудности, заключается в том, что вы пытаетесь свести все в единую сетку, но у вас нет элементов, которые естественно вписываются в сетку. Вы можете заставить его работать, используя множество невидимых столбцов и разумно используя columnspan, но есть и более простые способы.

В данном конкретном случае pack и несколько промежуточных кадров, на мой взгляд, являются лучшим решением.

Насколько я вижу, ваш пользовательский интерфейс состоит из четырех областей:

  1. Строка, в которой есть запись для int_entry и кнопка-флажок
  2. Строка с несколькими флажками и радиокнопками, а также запись
  3. Строка с переключателями «И» и «Или»
  4. Большая пустая область

Я бы сделал это, создав четыре кадра, по одному для каждой области:

frame1 = Frame(self, ...)
frame2 = Frame(self, ...)
frame3 = Frame(self, ...)
frame4 = Frame(self, ...)

Затем вы можете использовать pack, чтобы расположить эти кадры горизонтально. Все они заполняют свою область в горизонтальном направлении, а последний кадр занимает все остальные данные.

frame1.pack(side="top", fill="x")
frame2.pack(side="top", fill="x")
frame3.pack(side="top", fill="x")
frame4.pack(side="top", fill="both", expand=True)

Теперь вы можете добавлять виджеты в каждый кадр, не заботясь о том, как они влияют на остальную часть экрана.

Например, метка «Интерфейс», запись и кнопка-флажок «Любой» могут находиться в кадре 1. pack делает разумный выбор, поскольку вы хотите, чтобы они были выровнены по левому краю области (я полагаю...).

int_lbl = Label(frame1, text="Interface")
self.int_entry = Entry(frame1, width=15)
any_cb = Checkbutton(frame1, text="Any", ...)

int_lbl.pack(side="left")
self.int_entry.pack(side="left")
any_cb.pack(side="left")

Сделайте то же самое для других кадров. В каждом фрейме вы можете использовать pack или grid, если вы постоянно используете pack или grid для каждого виджета в фрейме. pack — очень естественный выбор, когда вы хотите, чтобы все ваши виджеты были выровнены в одном направлении в родительском виджете.

person Bryan Oakley    schedule 29.03.2017
comment
Спасибо, Брайан, это прекрасно работает, я ценю ваш быстрый ответ. - person Clyde; 29.03.2017