Виджеты сокращения размера Python tkinter - PullRequest
0 голосов
/ 24 сентября 2019

Я посмотрел на все остальные вопросы и ответы и не смог найти тот, который соответствует тому, что я пытаюсь сделать.

Код:

class GameWin:
    def __init__(self, master):
        self.master = master
        self.master.title("Title")

        self.main_frame = Frame(self.master, bd = 10, bg = uni_bg)
        self.main_frame.grid()

        self.left_frame = Frame(self.main_frame, bd = 10, bg = uni_bg)
        self.left_frame.grid(column = 0, row = 0)

        self.right_frame = Frame(self.main_frame, bd = 10, bg = uni_bg)
        self.right_frame.grid(column = 1, row = 0)

        self.right_frame.columnconfigure(0, weight = 1)
        self.right_frame.rowconfigure(0, weight = 1)
        self.right_frame.columnconfigure(1, weight = 1)
        self.right_frame.rowconfigure(1, weight = 1)

        self.web = Text(self.left_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bt_bg, fg = uni_fg)
        self.web.grid(column = 0, row = 0, padx = 5, pady = 5)

        self.output = Text(self.left_frame, font = (uni_font, 12), wrap = WORD, bg = "black", fg = uni_fg)
        self.output.grid(column = 0, row = 1, padx = 5, pady = 5, sticky = "ew")
        self.output.configure(state = "disabled")

        self.input = Entry(self.left_frame, font = (uni_font, 12))
        self.input.grid(column = 0, row = 2, sticky = "ew")
        self.input.bind('<Return>', self.submit)

        self.notepad = Text(self.right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_fg, fg = "black", width = 42)
        self.notepad.grid(column = 0, row = 0, pady = 5, rowspan = 2)

        self.sys_info = Text(self.right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bg, fg = uni_fg, width = 35, height = 11, bd = 0)
        self.sys_info.tag_configure('center', justify='center')
        self.sys_info.grid(column = 1, row = 0, pady = 5)
        self.sys_info.insert(END, "NAME", "center")
        self.sys_info.configure(state = "disabled")

        self.trace = Text(self.right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bg, fg = uni_fg, width = 35, height = 11)
        self.trace.grid(column = 1, row = 1, pady = 5)

        self.email = Text(self.right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bt_bg, fg = uni_fg)
        self.email.grid(column = 0, row = 2, pady = 5, columnspan = 2)
        self.email.configure(state = "disabled")

        self.respond = Entry(self.right_frame, font = (uni_font, 12))
        self.respond.grid(column = 0, row = 3, columnspan = 2, sticky = "ew")
        self.respond.bind('<Return>', self.do_respond)

    def submit(self, event):
        self.output.configure(state = "normal")
        self.output.configure(state = "disabled")
        pass

    def do_respond(self, event):
        pass

Изображение текущего экрана: https://i.imgur.com/P2B6E5y.png

Первое, что я пытаюсь выяснить, это как не указывать явно размер3 текстовых виджета в правом верхнем углу.Потому что у каждого экран разного размера.Если я не укажу размер явно, они расширяются, и все идет вразрез (так как текстовый виджет по умолчанию большой).Я хочу, чтобы виджеты автоматически уменьшали масштаб, чтобы поместиться в столбце (такой же ширины, как большой серый нижний правый текстовый виджет).Это вообще возможно?

Во-вторых, кадры и виджеты заполняют все пространство в окне.Будь то полноэкранный режим (как на картинке) или окно меньшего размера (и, надеюсь, их размер будет относительно друг друга).По краям окна много свободного места, и я хочу от этого избавиться.Я перепробовал все, что мог придумать, но не смог заставить их заполнить это пространство.

Я попытался поместить три верхних виджета каждый в свой фрейм, ограничив размер фреймов относительно окна.размер, и установка виджетов для заполнения этого кадра, но это не работает.Код, который я использовал, чтобы попробовать это: https://pastebin.com/3YWK9Xg2

class GameWin:
    def __init__(self, master):
        self.master = master
        self.master.title("Hacker")
        win_width = self.master.winfo_width()
        win_height = self.master.winfo_height()

        self.main_frame = Frame(self.master, bd = 10, bg = uni_bg)
        self.main_frame.grid(sticky = "nsew")

        self.left_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height), width = int(win_width/2))
        self.left_frame.grid(column = 0, row = 0, rowspan = 3)
        self.left_frame.grid_propagate(False)

        self.note_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height/2), width = int(win_width/4))
        self.note_frame.grid(column = 1, row = 0, rowspan = 2, sticky = "n")
        self.note_frame.grid_propagate(False)

        self.sys_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height/4), width = int(win_width/4))
        self.sys_frame.grid(column = 2, row = 0, sticky = "n")
        self.sys_frame.grid_propagate(False)

        self.trace_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height/4), width = int(win_width/4))
        self.trace_frame.grid(column = 2, row = 1, sticky = "n")
        self.trace_frame.grid_propagate(False)

        self.bottom_right_frame = Frame(self.main_frame, bd = 10, bg = uni_bg, height = int(win_height/2), width = int(win_width/2))
        self.bottom_right_frame.grid(column = 1, row = 2, columnspan = 2)
        self.bottom_right_frame.grid_propagate(False)

        self.web = Text(self.left_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bt_bg, fg = uni_fg)
        self.web.grid(column = 0, row = 0, padx = 5, pady = 5)

        self.output = Text(self.left_frame, font = (uni_font, 12), wrap = WORD, bg = "black", fg = uni_fg)
        self.output.grid(column = 0, row = 1, padx = 5, pady = 5, sticky = "ew")


        self.input = Entry(self.left_frame, font = (uni_font, 12))
        self.input.grid(column = 0, row = 2, sticky = "ew")
        self.input.bind('<Return>', self.submit)

        self.notepad = Text(self.note_frame, font = (uni_font, 12), wrap = WORD, bg = uni_fg, fg = "black")
        self.notepad.pack(fill = BOTH, expand = YES)

        self.sys_info = Text(self.sys_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bg, fg = uni_fg)
        self.sys_info.tag_configure('center', justify='center')
        self.sys_info.grid(sticky = "nsew")
        self.sys_info.insert(END, "NAME", "center")
        self.sys_info.configure(state = "disabled")

        self.trace = Text(self.trace_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bg, fg = uni_fg)
        self.trace.grid(sticky = "nsew")

        self.email = Text(self.bottom_right_frame, font = (uni_font, 12), wrap = WORD, bg = uni_bt_bg, fg = uni_fg)
        self.email.grid(row = 0, pady = 5, columnspan = 2, sticky = "nsew")
        self.email.configure(state = "disabled")

        self.respond = Entry(self.bottom_right_frame, font = (uni_font, 12))
        self.respond.grid(row = 1, columnspan = 2, sticky = "ew")
        self.respond.bind('<Return>', self.do_respond)

    def submit(self, event):
        self.output.configure(state = "normal")
        self.output.configure(state = "disabled")

    def do_respond(self, event):
        pass

и изображение результата: https://i.imgur.com/IVnw65x.png

Вот полный код: https://pastebin.com/Gm2ePqFH. Я хочу этопохоже, что это на первом рисунке, без необходимости явно указывать размер каждого текстового виджета.И я хочу, чтобы все остались одинакового размера относительно окна.

1 Ответ

1 голос
/ 24 сентября 2019

Если вы хотите, чтобы виджеты сжимались до размера столбца, лучше всего для меня работала стратегия, заключающаяся в том, чтобы сделать виджет очень маленьким, а затем использовать менеджер макета (pack, place или * 1003).*) сделать их больше, чтобы соответствовать.Вы можете либо сделать виджет 1x1, если это действительно минимальный размер, который вы примете, либо установить его в соответствии с тем, какой, по вашему мнению, должен быть абсолютный минимум (например, 4 строки по 20 символов, 20 строк по 10 символов и т. Д.).

Итак, начните с того, чтобы сделать эти виджеты как можно меньше.

Далее убедитесь, что вы используете атрибут sticky, чтобы виджеты увеличивались, чтобы заполнить выделенное им пространство.Вам также необходимо убедиться, что вы используете атрибут sticky для self.right_frame, чтобы он также занимал свое место.

Наконец, убедитесь, что вы вызываете rowconfigure и columnconfigure, чтобы установить положительный вес для любого виджета, дочерние элементы которого управляются grid.Вы делаете это не для self.master и не для 1011 * и self.right_frame

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

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

Кроме того, не пытайтесь решить все проблемы с макетом сразу.В вашем случае я бы решил проблему следующим образом:

  • Начните с вашего mainframe и получите его так, чтобы он заполнил содержащее окно.Убедитесь, что вы вручную изменили размер окна, чтобы увидеть, как оно растет и сжимается.

  • Затем добавьте левую и правую рамки.Убедитесь, что они растут и уменьшаются до размеров mainframe.

  • Далее, сфокусируйтесь только на виджетах в левом фрейме.Добавьте их, и убедитесь, что они сжимаются и подходят.

  • Затем сфокусируйтесь на правой рамке.Добавьте их и убедитесь, что они сжимаются и подходят.

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

Например, вместо этого:

self.web = Text(...)
self.web.grid(...)
self.output = Text(...)
self.output.grid(...)
self.input = Text(...)
self.input.grid(...)
self.notepad = Text(...)
self.notepad.grid(...)

Сделайте это:

self.web = Text(...)
self.output = Text(...)
self.input = Text(...)
self.notepad = Text(...)

self.web.grid(...)
self.output.grid(...)
self.input.grid(...)
self.notepad.grid(...)

После этого вы можете сразу же ответить на вопрос «как определены мои виджеты?» И «как расположены мои виджеты».При том, что у вас есть сейчас, на эти вопросы очень сложно ответить.

...