wxPython應用心得


在遍找可以拖拽設計wxPython窗體沒找到如意的后,只有把wxPython學一學了,一個簡單的項目完成后,總結一些小心得:

  • StaticText控件改變里面的內容用SelLabel方法
  • 整體布局用GridBagSizer,因為你只要告訴sizer你把某個控件插在哪一行哪一列,同時告知橫跨多少行多少列即可
bag=wx.GridBagSizer(5,5)#生成行列間距為5的布局控件 bag.Add(btn1,pos=(0,0))#第1行第一列加入一個按鈕 bag.Add(label1,pos=(0,1),span(1,3),flag=wx.LEFT|wx.RIGHT|wx.GROW,border=10) #第一行第二列加入一個label,並且橫跨3列,並且左右邊距為10像素,注意wx.LEFT等參數其實是作用於border參數的,請仔細理解這一個例子 #同時根據窗口大小自動填充(GROW等同於EXTEND,唯一的區別就是可以少打兩個字) 
    • 一行布局用FlexGridSizer  
      很遺憾,一個一個的元素想要像html一樣地流式排開是不可能的,所以哪怕是幾個簡單的控件,也是要用布局控件的,不然只有絕對定位了,不定位或布局的話,所有控件會出現在(0,0)的位置。。。  
      FlexGridSizer的好處在於每列寬度可以不一樣,這樣你只要元素一個個地丟到格子里,格子的大小會隨着里面控件的大小而自動調整,這就類似於“流式布局”了  
      形如 第3/8頁 首頁 上一頁 下一頁 末頁 的分頁工具條:
def getPager(self):     #工具條所需要的控件:label和button     pt1=wx.StaticText(self,-1,"第")     pt2=wx.StaticText(self,-1,"/")     pt3=wx.StaticText(self,-1,"頁")     lblPageIndex=wx.StaticText(self,-1,"0")     lblPageCount=wx.StaticText(self,-1,"0")     btnFirst=wx.BitmapButton(self,-1,myres.getfirstBitmap(),style=0,size=(15,15))#用圖片做按鈕,style=0可以讓圖片無邊框     btnLast=wx.BitmapButton(self,-1,myres.getlastBitmap(),style=0,size=(15,15))     btnPrev=wx.BitmapButton(self,-1,myres.getprevBitmap(),style=0,size=(15,15))     btnNext=wx.BitmapButton(self,-1,myres.getnextBitmap(),style=0,size=(15,15))     #生成sizer,把控件丟進去     fg=wx.FlexGridSizer(hgap=2,vgap=2)#單元格間隔為2     gb.Add(pt1,0,0)     gb.Add(lblPageIndex,0,1)     gb.Add(pt2,0,2)     gb.Add(lblPageCount,0,3)     gb.Add(pt3,0,4)     gb.Add(btnFirst,0,5)#如此反復     #比BoxSizer要好用 
  • 關於Layout()方法:  
    很多情況下控件內容改了,需要強制調用Layout方法來重新布局,比如上面的分頁條,第3/1506頁,是緊緊挨在一起的,其實是三個label,一旦你翻頁到了最后一頁,3變成1506,你會發現根本看不清,因為它的寬度還是”3“的寬度,SetLabel()后再Layout(),你會發現寬度自然變了 
  • 關於表格和“數據源”  
    .net編程過來的喜歡用“數據源”的概念  
    大量數據的呈現在wxPython里面用的是Grid,最簡單的用法是CreateGrid,然后再給單元格賦值,這種情況顯然不適合分頁數據,Grid里面可以隨時改變一個Grid里面數據的方法就是SetTable()  
    使用SetTable()方法的關鍵在於要做好一個"Table",我是這么做的:
#-*- encoding:UTF-8 -*-
import wx import wx.grid #繼承wx.Grid.PyGridTableBase即可,然后重寫下面一些必要的方法 class myTable(wx.grid.PyGridTableBase):     def __init__(self,datasource):         '''         [             {colname:value,columane:value2...},             {colname:value,columane:value2...},             {colname:value,columane:value2...},             ...         ]         '''         wx.grid.PyGridTableBase.__init__(self)         self.data={}         self.colLabels=datasource[0].keys()#用於生成列頭的列表         self.rows=len(datasource)#行數         self.cols=len(datasource[0].keys())#行數         i=0         for rowin datasource:             j=0             for k,vin row.items():                 self.data[(i,j)]=str(v)#給每一個單元格賦值的方法                 j+=1             i+=1         #沒必要隔行換色,我就沒用網上各種現成的odd和even的做法了,只設置一個屬性:讓超長的文字不跨到別的單元格里去(默認會跨的)         self.cell=wx.grid.GridCellAttr()         self.cell.SetOverflow(False)     # these five are the required methods     def GetNumberRows(self):         return self.rwos     def GetNumberCols(self):         return self.cols               def GetColLabelValue(self,col):#列頭         return self.colLabels[col]           #同樣你可以實現自己的行頭 GetRowLabelValue,只要return適當的值就可以了     def IsEmptyCell(self, row, col):         return self.data.get((row, col))is not None     def GetValue(self, row, col):#為網格提供數據         value= self.data.get((row, col))         if valueis not None:             return value         else:             return ''     def SetValue(self, row, col, value):#給表賦值         self.data[(row,col)]= value     # the table can also provide the attribute for each cell     def GetAttr(self, row, col, kind):         attr= self.cell         attr.IncRef()#暫時沒看懂         return attr     '''假如你送的數據源沒有列頭信息,如下:     [         [value1,value2,value3,...],         [value1,value2,value3,...],         [value1,value2,value3,...],         ...     ]     你需要做的改動不過是把列頭的相關代碼注釋掉     '''     #使用     gv=wx.Grid()     #插一點Grid的技巧:     gv.SetRowLabelSize(20)#默認行頭很寬,設置一下,不過一旦設置了,行頭的寬度就不可拖動了     gv.EnableEditing(False)#默認表格是可以全表編輯的,這里關閉     gv.EnableDragRowSize(False)#默認表格的每格是可以拖動高度的,這里關閉     gv.SetDefaultCellOverflow(False)#貌似沒起什么作用,所以才在table里面自行設了overflow     result=myprocess.gettable()     dt=myTable(result)#得到數據后轉化成我需要的數據源     gv.ClearGrid()#清空表格     gv.SetTable(dt)     gv.Hide()     gv.Show()#假如gv是之前做的,沒有列頭信息,這是我找到的唯一刷新列頭的方法,就是hide然后show一下。。。希望有更靠譜的做法 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM