2016-03-28 57 views
2

我正在爲基於文本的遊戲設計一個真正基本的佈局。爲什麼第一列中的文本在字符串結尾之前停止,爲什麼窗口如此之高?代碼如下,任何幫助表示讚賞。Tkinter帶文本的基本佈局

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) 

我不完全知道你在eman的「第一列中的文字[在字符串結束之前停止]」。我沒有看到它停止,我看到它正如我所期望的那樣包裹着,就像你指示的那樣。您設置了10個字符的寬度,並將其包含在單詞邊界處。

此外,當您使用grid時,作爲一個經驗法則,您必須至少給出一行和一列的權重。重量是Tkinter知道如何分配任何額外空間的重量。注意如果調整窗口大小,內部的小部件不會增長或縮小。這是因爲它們所在的行和列的默認權重爲0(零)。

要改變這種情況,請使用row_configurecolumn_configure。例如,如果你想在藍色區域擴展爲佔用所有額外的空間,給它的行和列的1(一)重量:

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

如果你這樣做,你會發現.... 。 沒有什麼變化。 Tkinter確實會爲第0行和第1列提供額外的空間。但是,您還有更多的事情需要做。當調用grid來請求小部件「粘」到給予它的空間的邊緣時,您需要使用sticky屬性。

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:當使用共享相同父項的小部件時,必須避免混合網格和包。這沒有問題 - 甚至更可取! - 在整個應用程序中使用它們。 –