2016-03-28 2 views
2

Я борюсь с действительно основным макетом для текстовой игры. Почему текст в первом столбце останавливается до конца строки, и почему окно настолько высокое? Код ниже, любая помощь оценивается.Tkinter Basic Layout с текстом

from Tkinter import * 
import tkFont 

class TreasureHunt: 

    def __init__(self, master): 
     app = Frame(master) 
     app.grid() 

     self.mono_font = tkFont.Font(family="monospace",size=24,weight="bold") 
     self.instructions = "Find the hidden treasure!\n\nUse the arrow keys to select where to look, then press Enter to check. \ 
     There is a 50/50 chance you will be told the distance from the treasure. Keep hunting until you find it. Good luck!" 

     self.info = Text(app, wrap=WORD, padx=10, pady=10, bd=0,width=10) 
     self.info.insert(1.0,self.instructions) 
     self.info.grid(row=0,column=0,sticky=N) 

     self.island = Text(app, bg="cyan",bd=0, padx=20, pady=20, font=self.mono_font,width=20) 
     self.island.insert(1.0, "ready") 
     self.island.grid(row=0,column=1) 

     self.display_grid() 

    def display_grid(self): 
     self.matrix = [["# " for col in range(8)] for row in range(8)] 
     for row in range(len(self.matrix)): 
      row_str = "".join(self.matrix[row]) +"\n" 
      self.island.insert(1.0,row_str) 


root = Tk() 
game = TreasureHunt(root) 
root.mainloop() 
+0

Я не понимаю эту часть вопроса: «Почему текст в первом столбце останавливается до конца строки» , Мне кажется, что он не «останавливается» для меня - он переносится на следующую строку. Это то, что вы имели ввиду? –

+0

С кодом, как есть, текст останавливается на «сокровище». «Продолжайте охотиться, пока не найдете ее. Удачи!» пропал, отсутствует. Я предполагаю, что вертикальное пространство первого столбца заполнено, хотя оно выглядит иначе из-за вертикальной высоты правого столбца. – Robin

ответ

1

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

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

self.island = Text(app, ..., height=9) 

Я не знаю, что вы Эман на «текст в первой колонке [останавливается] до конца строки». Я не вижу, чтобы он останавливался, я вижу, что он обертывается так, как я ожидал, и так же, как вы его инструктировали. Вы устанавливаете ширину в 10 символов и должны сообщать об этом в границах слов.

Кроме того, когда вы используете grid, как правило, вы должны указать хотя бы один ряд и один столбец весом. Вес заключается в том, как Tkinter знает, как выделить дополнительное пространство. Обратите внимание, что если вы изменяете размер окна, виджеты внутри не растут и не сокращаются. Это потому, что строки и столбцы, в которых они находятся, имеют значение по умолчанию 0 (ноль).

Чтобы изменить это, используйте row_configure и column_configure. Например, если вы хотите, синяя область расширить, чтобы занять все дополнительное пространство, дать это строка и столбец масса 1 (один):

app.grid_rowconfigure(0, weight=1) 
app.grid_columnconfigure(1, weight=1) 

Если вы сделаете это вы найдете .... ничего не меняется. Tkinter действительно предоставит дополнительное пространство для строк 0 и столбца 1. Однако вам нужно больше сделать. Вы должны использовать атрибут sticky при вызове grid, чтобы просить, чтобы виджет «прилипал» к краям предоставленного ему пространства.

self.info.grid(row=0,column=0,sticky=N+S+E+W) 
... 
self.island.grid(row=0,column=1,sticky=N+S+E+W) 

Когда вы это сделаете, вы увидите .... ничего не меняется. Это потому, что app является фреймом, и этот фрейм находится внутри корневого окна. Однако вы не указали вес для строки и столбца, в котором находится app, и вы также не указали для него значение sticky.

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

Попробуйте изменить эту строку:

app.grid() 

... к этому:

app.pack(fill="both", expand=True) 

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

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

app.grid_columnconfigure(0, weight=1) 

Обратите внимание, что оба внутренних виджета расширяются. Столбы имеют одинаковый вес, поэтому они расширяются одинаково. Чтобы получить право на расширение вдвое больше, чем налево, установите его вес на 2.

+0

Спасибо. Я действительно ценю такое глубокое объяснение базовых понятий. Мне любопытно, хотя - я понял, что смешивание сетки и пакета не было, но здесь приложение упаковано, но grid_columnconfig, похоже, ссылается на базовую сетку. Является ли ситуация похожей на «мы собираем рамку приложения в корневое окно для простоты, но если другие виджеты в этом фрейме используют сетку, выделите эти веса?» – Robin

+0

@Robin: смешать сетку и пакет следует избегать при использовании обоих с виджетами, которые имеют один и тот же родитель. Это не проблема - и даже предпочтительнее! - использовать как в приложении в целом. –

Смежные вопросы