2011-10-03 22 views
0

背景 作爲python的新手以及GUI編程,我想創建一個基於wxpython的GUI應用程序。此GUI將運行一系列測試用文本文件編寫的測試將會運行,並且它的步驟應顯示在窗口中。爲了選擇一個特定的測試,點擊該特定測試的複選框(下圖中的CheckListCtrl)。測試的結果將在MulilineTextCtrl_2Log在wxpython中的面板安排

顯示的窗口應該是這樣的:

我的ASCII藝術不是那麼好,但是反正

|-------------------------------------------------------------| 
|WINDOW TITLExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_[]X| 
|xxx[SelectAll]xxxxxx[DeselectAll]xxxxxxxxxxxxxxxxxxxxxxxxxxxx|  
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| 
|[CheckListCtrl] [MultilineTexTCtrl_1]xxxxxxxxxxxxxxxxxxxxxxxx| 
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| 
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[Refresh]xxx| 
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[Execute]xxx| 
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| 
|xxxxxxx[MulilineTextCtrl_2Log]xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|  
|_____________________________________________________________| 

我曾經有過創造了boxsizers麻煩這個窗口。我有麻煩可視化面板

TestList = [('Test1', 'Test1Description1', 'base'),  ('Test2', 'Test1Description1', 'base'),'Test3', 'Test1Description3', 'base'),] 

class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin): 
    def __init__(self, parent): 
     wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER) 
     CheckListCtrlMixin.__init__(self) 
     ListCtrlAutoWidthMixin.__init__(self) 

class MainGUI(wx.frame): 


panel = wx.Panel(self, -1) 

     vbox = wx.BoxSizer(wx.VERTICAL) 
     hbox = wx.BoxSizer(wx.HORIZONTAL) 
     #topPanel = wx.Panel(panel,-1) 
     topPanel = wx.Panel(panel, -1,pos=(0,0)) 
     bottomPanel = wx.Panel(panel, -1,pos=(1,0)) 


     self.log = wx.TextCtrl(bottomPanel, -1, style=wx.TE_MULTILINE) 
     self.list = CheckListCtrl(bottomPanel) 
     self.list.InsertColumn(0, 'TestID', width=140) 
     self.list.InsertColumn(1, 'TestDescription') 

     for i in TestList: 
      index = self.list.InsertStringItem(sys.maxint, i[0]) 
      self.list.SetStringItem(index, 1, i[1]) 
      self.list.SetStringItem(index, 2, i[2]) 

     vbox2 = wx.BoxSizer(wx.VERTICAL) 

     sel = wx.Button(topPanel, -1, 'Select All', size=(100, -1)) 
     des = wx.Button(topPanel, -1, 'Deselect All', size=(100, -1)) 

     refresh = wx.Button(bottomPanel, -1, 'Refresh', size=(100, -1)) 
     apply = wx.Button(bottomPanel, -1, 'Execute', size=(100, -1)) 



     self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id=sel.GetId()) 
     self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id=des.GetId()) 
     self.Bind(wx.EVT_BUTTON, self.OnRefresh, id=refresh.GetId()) 
     self.Bind(wx.EVT_BUTTON, self.OnExecute, id=apply.GetId()) 

     vbox2.Add(sel, 0, wx.TOP, 5) 
     vbox2.Add(des) 
     vbox2.Add(apply,wx.RIGHT) 
     vbox2.Add(refresh) 


     topPanel.SetSizer(vbox2) 

     vbox.Add(self.list, 1, wx.EXPAND, 3) 
     vbox.Add((-1, 10)) 
     vbox.Add(self.log, 0.5, wx.EXPAND) 
     vbox.Add((-1, 10)) 

     bottomPanel.SetSizer(vbox) 

     hbox.Add(bottomPanel, 0, wx.EXPAND | wx.RIGHT, 5) 


     panel.SetSizer(hbox) 

     self.Centre() 
     self.Show(True) 

def OnSelectAll(self, event): 
    num = self.list.GetItemCount() 
    for i in range(num): 
     self.list.CheckItem(i) 

def OnDeselectAll(self, event): 
    num = self.list.GetItemCount() 
    for i in range(num): 
     self.list.CheckItem(i, False) 

def OnRefresh(self, event): 
    num = self.list.GetItemCount() 
    for i in range(num): 
     if i == 0: self.log.Clear() 
     if self.list.IsChecked(i): 
      self.log.AppendText(self.list.GetItemText(i) + '\n') 

def OnExecute(self, event): 
    num = self.list.GetItemCount() 
    for i in range(num): 
     if i == 0: self.log.Clear() 
     if self.list.IsChecked(i): 
      self.log.AppendText(self.list.GetItemText(i) + '\n') 

app = wx.App() 
MainGUI(None, -1, 'Tester') 
app.MainLoop() 

回答

2

我向你推薦使用wxglade來設計你的圖形用戶界面的創建。它快速而有效,在您有一些經驗後,您可以完成大部分手動操作。

wxglade沒有wx.lib小部件,例如CheckListCtrlMixinListCtrlAutoWidthMixin您正在使用或組合,如您的類CheckListCtrl

爲了能夠使用這些,使用可用的窗口部件(pe wx.panel)臨時填充GUI中的插槽,然後在生成代碼後,手動將wx.Panel實例化替換爲你的特殊或習俗課程。

最後,您的代碼有一些主要問題會產生異常,如wx.frame(對於wx.Frame),壞縮進或未定義的TestList。您的MainGUI類沒有__init__方法,並且不會初始化父項wx.Frame。此外,bottomPanel被添加到hbox尺寸,但不是topPanel

你寫不產生GUI結構你描述但這兩個面板的幾個部件的組織:

enter image description here

更接近你的描述,你至少需要添加一些額外分級機。 使用wxglade,它會爲你做所有事情。

在這裏,你有wxglade生成的代碼的設計像你這樣(與替代wx.ListCtrlCheckListCtrl

#!/usr/bin/env python 
# -*- coding: iso-8859-15 -*- 
# generated by wxGlade HG on Tue Oct 04 12:45:03 2011 

import wx 

# begin wxGlade: extracode 
# end wxGlade 

class MainGUI(wx.Frame): 
    def __init__(self, *args, **kwds): 
     # begin wxGlade: MainGUI.__init__ 
     kwds["style"] = wx.DEFAULT_FRAME_STYLE 
     wx.Frame.__init__(self, *args, **kwds) 
     self.button_3 = wx.Button(self, -1, "Select All") 
     self.button_4 = wx.Button(self, -1, "DeselectAll") 
     self.list_ctrl_1 = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER) 
     self.text_ctrl_1 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE) 
     self.button_1 = wx.Button(self, -1, "Refresh") 
     self.button_2 = wx.Button(self, -1, "Execute") 
     self.text_ctrl_2 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE) 

     self.__set_properties() 
     self.__do_layout() 
     # end wxGlade 

    def __set_properties(self): 
     # begin wxGlade: MainGUI.__set_properties 
     self.SetTitle("frame_1") 
     self.SetBackgroundColour(wx.Colour(255, 170, 5)) 
     self.list_ctrl_1.SetMinSize((200, 264)) 
     # end wxGlade 

    def __do_layout(self): 
     # begin wxGlade: MainGUI.__do_layout 
     sizer_1 = wx.BoxSizer(wx.VERTICAL) 
     sizer_2 = wx.BoxSizer(wx.HORIZONTAL) 
     sizer_3 = wx.BoxSizer(wx.VERTICAL) 
     sizer_4 = wx.BoxSizer(wx.HORIZONTAL) 
     sizer_4.Add(self.button_3, 0, wx.ALL, 5) 
     sizer_4.Add(self.button_4, 0, wx.ALL, 5) 
     sizer_4.Add((20, 20), 1, wx.EXPAND, 0) 
     sizer_1.Add(sizer_4, 0, wx.EXPAND, 0) 
     sizer_2.Add(self.list_ctrl_1, 0, wx.ALL|wx.EXPAND, 5) 
     sizer_2.Add(self.text_ctrl_1, 0, wx.ALL|wx.EXPAND, 5) 
     sizer_3.Add(self.button_1, 0, wx.ALL, 5) 
     sizer_3.Add(self.button_2, 0, wx.ALL, 5) 
     sizer_2.Add(sizer_3, 0, wx.EXPAND, 0) 
     sizer_1.Add(sizer_2, 1, wx.EXPAND, 0) 
     sizer_1.Add(self.text_ctrl_2, 0, wx.ALL|wx.EXPAND, 5) 
     self.SetSizer(sizer_1) 
     sizer_1.Fit(self) 
     self.Layout() 
     # end wxGlade 

# end of class MainGUI 

if __name__ == "__main__": 
    app = wx.PySimpleApp(0) 
    wx.InitAllImageHandlers() 
    frame_1 = MainGUI(None, -1, "") 
    app.SetTopWindow(frame_1) 
    frame_1.Show() 
    app.MainLoop() 

而且外觀:

enter image description here

注意,如對方稱回答,沒有必要將你的小部件放在面板(widget(panel,..))和sizers中的面板上,它可以工作,但最好只是把你的小部件(作爲框架的孩子 - >widget(self,..))在尺寸(sizerx.Add(widget,..))和尺寸大小(sizery.Add(sizerx))中構建結構。
通常你不會修改這段代碼。您將它劃分子類來添加您的功能或任何您需要的奇特添加。通過這種方式,您可以再次使用wxglade來更改小部件的位置,以添加其他小部件或大小調整器並重新生成完整文件。

+0

謝謝@jaoquin縮進問題是由於複製粘貼錯誤。我故意遺漏了一些東西來使代碼更小。 – user974168

+0

@ user974168然後最好消除'self.Bind'或者循環來填充TestList,以便維護代碼的功能以及所需的所有Widget插槽。答案有幫助嗎?否則,如果您提供了更精確的設計(例如,您給出的設計與設計中的小部件名稱和代碼之間沒有關係,則清單控件無法適用一個單行插槽,並不清楚TextCtrl是單行還是多行,在這最後一種情況下,它將垂直延伸多少 – joaquin

+0

@jaoquin我已更新問題 – user974168

1

你並不需要所有那些額外的面板。事實上,除了wx.Notebooks等之外,你幾乎不需要多於一個。相反,我發現最簡單的方法是將其繪製在一張紙上,然後在東西周圍繪製矩形。爲此,我將有一個主要的BoxSizer垂直定向。然後,我會使用兩個水平BoxSizer作爲按鈕,另一個使用控件。如果您必須以這種方式定位其他三個單個小部件,那麼您可能需要其他一些帶有間隔符的BoxSizer。無論如何,一旦您在各種BoxSizer中擁有小部件,您將它們添加到MainSizer中即可完成。

或者你可以使用一個GridSizer和最後三個的一些間隔符。

+0

因此,如果我理解你是正確的,我們可以將Ctrls添加到一個單個面板在Boxsizers的幫助下。 – user974168

+0

是的,除非你想要多個面板出於某種原因,我很少看到需要它們的理由。 –