2012-08-31 71 views
3

我正在學習wxPython,並且我正在嘗試寫一個學生信息管理器。我一直在編寫CLI程序很多年,所以我沒有太多的GUI製作經驗。wxPython:sizers,grids讓我瘋狂

首先,我畫了我的UI的藍圖。 A blueprint of my UI

然後,我試圖讓它在wxPython中,但sizers真的讓我發瘋。我以前從未使用過任何類型的篩選器! (Visual Basic中是我學到的第一語言^ __ ^)

最後,我寫了這個代碼:

import wx 
from wx.lib import sheet 


class Sheet(sheet.CSheet): 
    def __init__(self, parent, row, col): 
     sheet.CSheet.__init__(self, parent) 
     self.row = self.col = 0 
     self.SetNumberRows(row) 
     self.SetNumberCols(col) 

     for i in range(row): 
      self.SetRowSize(i, 20) 


class ChartPanel(wx.Panel): 
    '''This is the panel for the chart, but the still working on it. ''' 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 


class MainPanel(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     sizer = wx.GridBagSizer(5, 5) 

     # However, just put the chart into main frame. 
     chart = ChartPanel(self) 
     chart.SetBackgroundColour("blue") 

     Students = Sheet(self, 5, 2) 
     History = Sheet(self, 2, 2) 

     button1 = wx.Button(self, label="Button #1") 
     button2 = wx.Button(self, label="Button #2") 
     button3 = wx.Button(self, label="Button #3") 

     sizer.Add(Students, pos=(0, 0), span=(5, 2), flag=wx.EXPAND) 
     sizer.Add(History, pos=(0, 2), span=(2, 2), flag=wx.EXPAND) 
     sizer.Add(chart, pos=(2, 2), span=(3, 2), flag=wx.EXPAND) 

     sizer.Add(button1, pos=(5, 0), span=(1, 1)) 
     sizer.Add(button2, pos=(5, 1), span=(1, 1)) 
     sizer.Add(button3, pos=(5, 2), span=(1, 1)) 

     sizer.AddGrowableCol(5) 
     sizer.AddGrowableRow(5) 

     self.SetSizer(sizer) 
     self.Fit() 


class MainFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, title="BoxSizer Example") 
     panel = MainPanel(self) 
     self.Show() 

if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MainFrame() 
    app.MainLoop() 

但這個程序是醜陋和馬車。有人可以教我如何以智能的方式使用sizers,並幫助我修改我的代碼嗎?

非常感謝!

+0

我知道你的感受,所以首先現在很多很多人都明白你徹底沮喪......瞭解施膠劑我試着閱讀關於sizer的許多文檔,但是我最終通過將它想像爲HTML中的CSS來獲得它,所以請閱讀這個http://www.htmldog。com/guides/cssbeginner/margins/AND後面的頁面,我發現它很好地解釋了CSS,它和sizers一樣是一個佈局模型....我簡直不敢相信我記得那個鏈接有一段時間是我讀的它猜測它表明它是很好的營銷。 – Zimm3r

回答

2

首先,我不得不刪除你的​​和AddGrowableRow()行,因爲他們給了我錯誤。我爲這些功能讀了documentation,我不認爲你想給他們打電話(但只有你知道你想如何看你的UI)。

你實際上似乎對sizer有很好的把握。問題是MainPanel不知道MainFrame的大小,所以部分UI被切斷。解決這個問題很簡單,你有兩個選擇。

選項1
MainFrame.__init__(),放置panel施膠機的內部。這將允許sizer根據MainFrame的大小設置panel的大小。現在它們的尺寸之間沒有關係。這種變化將是這樣的:

class MainFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, title="BoxSizer Example") 
     panel = MainPanel(self) 
     sizer = wx.BoxSizer(wx.HORIZONTAL) 
     sizer.Add(panel) 
     self.SetSizer(sizer) #this allows panel and MainFrame to influence each other's sizes 
     self.Show() 
     self.Fit() 

選項2
MainFrame只中有1個對象,MainPanel。那麼爲什麼不把這兩個類合併爲一個呢?只需將MainPane1中的所有代碼添加到MainFrame,然後刪除MainPanel即可。重要的部分是MainPanel.__init__()調用SetSizer()。如果您將該代碼移動到MainFrame.__init__()那麼您仍然按照我在選項1中所建議的方式執行,但您的課程少一個。這看起來像這樣:

class MainFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, title="BoxSizer Example") 
     sizer = wx.GridBagSizer(5, 5) 

     # However, just put the chart into main frame. 
     chart = ChartPanel(self) 
     chart.SetBackgroundColour("blue") 

     Students = Sheet(self, 5, 2) 
     History = Sheet(self, 2, 2) 

     button1 = wx.Button(self, label="Button #1") 
     button2 = wx.Button(self, label="Button #2") 
     button3 = wx.Button(self, label="Button #3") 

     sizer.Add(Students, pos=(0, 0), span=(5, 2), flag=wx.EXPAND) 
     sizer.Add(History, pos=(0, 2), span=(2, 2), flag=wx.EXPAND) 
     sizer.Add(chart, pos=(2, 2), span=(3, 2), flag=wx.EXPAND) 

     sizer.Add(button1, pos=(5, 0), span=(1, 1)) 
     sizer.Add(button2, pos=(5, 1), span=(1, 1)) 
     sizer.Add(button3, pos=(5, 2), span=(1, 1)) 

     #I removed these lines because they gave me errors and I don't understand why you needed them 
     #sizer.AddGrowableCol(5) 
     #sizer.AddGrowableRow(5) 

     self.SetSizer(sizer) 
     self.Fit() 
     self.Show() 

最後,我不喜歡使用wx.GridBagSizer。我更喜歡使用嵌套的wx.BoxSizer對象。我發現我獲得了更多的控制權,並允許我從代碼中可視化我的UI的外觀,因爲我將UI分解爲更小的塊。然而,這是一個個人喜好的問題,你應該使用你理解的任何方法,並且對感到滿意。看看你的藍圖,我看到有兩列。所以首先我們需要一個sizer來處理這些列。然後,每列可以分成兩行。並且按鈕需要多一個分級機來保存它們。該代碼是這樣的:

def __init__(self, parent): 
    wx.Panel.__init__(self, parent) 
    mainSizer = wx.BoxSizer(wx.HORIZONTAL) #this will make the columns 

    rightSizer = wx.BoxSizer(wx.VERTICAL) #this will be the rows on the right 
    # However, just put the chart into main frame. 
    chart = ChartPanel(self) 
    chart.SetBackgroundColour("blue") 
    History = Sheet(self, 2, 2) 

    rightSizer.Add(History, 1, wx.EXPAND) 
    rightSizer.Add(chart, 1, wx.EXPAND) 

    leftSizer = wx.BoxSizer(wx.VERTICAL) #this will be the rows on the left 
    Students = Sheet(self, 5, 2) 

    buttonSizer = wx.BoxSizer(wx.HORIZONTAL) #this will organize the buttons 
    button1 = wx.Button(self, label="Button #1") 
    button2 = wx.Button(self, label="Button #2") 
    button3 = wx.Button(self, label="Button #3") 

    buttonSizer.Add(button1) 
    buttonSizer.Add(button2) 
    buttonSizer.Add(button3) 

    leftSizer.Add(Students, 1, wx.EXPAND) 
    leftSizer.Add(buttonSizer) 

    mainSizer.Add(leftSizer, 1, wx.EXPAND) 
    mainSizer.Add(rightSizer, 1, wx.EXPAND) 

    self.SetSizer(mainSizer) 
    self.Fit() 
+0

謝謝。但是我仍然有兩個問題:1.當用戶調整窗口大小時,我希望窗口小部件更改大小。 2.框架中的三個按鈕佔用太多空間,我希望它們看起來與我的藍圖相似。 –

+0

然後你需要使按鈕變小。創建按鈕時,必須設置按鈕的大小。除此之外,'wx.EXPAND'標誌應該表示其他所有內容都隨窗口調整大小。 – acattle

+0

謝謝。嵌套sizers非常有用! –