Tkinter с Tcl / TK 8.6: добиться "ширины столбца" с помощью pack ()

Я нахожусь в ситуации, когда я должен использовать только .pack() или .grid() для достижения определенных размеров виджетов, когда они расположены рядом друг с другом.

Раньше я смешивал .pack() с .grid(), основываясь на знаниях, полученных в этом посте:

В каких случаях сетку Tkinter () нельзя смешивать с pack ()?

то есть, имея кадры, упакованные рядом друг с другом, но внутри каждого кадра у меня есть сетки. Он работал нормально, пока я не обновил бэкэнд Tcl / TK до 8.6.8 в официальном Python 3.7.2, когда я начинаю видеть проблемы интерпретатора:

_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack

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

Должен ли я сделать все для этого в .grid(), или в .pack() есть секретные ингредиенты, которых я не видел в документации?

В идеале я рассчитываю достичь следующего

  1. В ряду виджетов виджеты расположены рядом друг с другом и максимально заполняют пространство, аналогично .pack(side='left', fill='x', expand=True).
  2. В той же строке я все еще могу указать, чтобы один виджет был шире остальных, так что при настройке всего на expand=True относительные размеры все еще контролируются.

Пример

В macOS следующий код дает мне более широкий вход и более узкий ползунок, в то время как я бы хотел наоборот, только с .pack().

import tkinter as tk
import tkinter.ttk as ttk


root = tk.Tk()
mainframe = tk.Frame(root, bg='blue')
mainframe.pack()
row1 = tk.Frame(mainframe, bg='red')
entry = ttk.Entry(row1, text='Search...')
slider = ttk.Scale(row1)
btn1 = ttk.Button(row1, text='Reset')
btn2 = ttk.Button(row1, text='Help')

entry.pack(side='left', fill='x', expand=True)
slider.pack(side='left', fill='x', expand=True)
btn1.pack(side='left', fill='x', expand=True)
btn2.pack(side='left', fill='x', expand=True)
row1.pack()

root.mainloop()

Я должен подчеркнуть, что я знаю, как использовать .grid() с моими «строками», используя .grid_columnconfigure(col, weight), который работал. Просто мой рабочий код (более сложный, чем приведенный выше пример, конечно) просто сломался после обновления до TK 8.6, что означает, что по мере того, как мой проект становится больше, смешанных менеджеров будет все труднее поддерживать. Поэтому я решил выбрать лагерь между .pack() и .grid(). Если один может достичь всего, чего может другой, ценой, это было бы здорово.

Сообщение об ошибке сообщает вам, что именно не так - вы используете как сетку, так и пакет в корневом окне. Как сказано в вопросе, на который вы ссылаетесь, вы не можете этого сделать.

Bryan Oakley 27.12.2018 01:44

@BryanOakley Да. Мой вопрос не в этом, а в том, как добиться размеров порций с помощью ряда виджетов только с помощью .pack(). Я обновлю свой вопрос соответственно.

kakyo 27.12.2018 01:54

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

Bryan Oakley 27.12.2018 01:57

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

martineau 27.12.2018 02:06

@martineau Я обновил вопрос примером. Спасибо.

kakyo 27.12.2018 04:38
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
215
2

Ответы 2

Лично я бы делал все в .grid (), потому что его проще поддерживать и намного проще, когда все становится сложнее, чем .pack (). Некоторое время назад я использовал pack, и мне потребовалось много времени, чтобы сделать что-то, потому что вещи заканчивались там, где я этого не хотел. Подробнее о размере столбца сетки: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/grid-config.html и Tkinter настроить ширину столбца

P.S. если вы занимаетесь созданием графического интерфейса, существует библиотека под названием Kivy, которая отлично подходит для такого рода вещей, просто проверьте ее (https://kivy.org/#home), если вас интересует, иначе - используйте сетку.

Спасибо за идеи. Я знаю о Kivy, Qt, wx и т. д. Многие из них - отличные решения. Прямо сейчас я хотел бы использовать стандартное решение среды выполнения Python для упрощения распространения.

kakyo 27.12.2018 04:41

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

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

Другие вопросы по теме