2013-07-22 86 views
2

我在互聯網上看到很多關於此的文章,但沒有任何建議可行。Python/wxWidgets:在包裝好的StaticText中垂直對齊文本

這裏是我的測試代碼:

import wx 
class DisplayText(wx.Dialog): 

    def __init__(self, parent, text="", displayMode=0): 

     # Initialize dialog 
     wx.Dialog.__init__(self, parent, size=(480,320), style=(wx.DIALOG_EX_METAL | wx.STAY_ON_TOP)) 

     # Freeze UI so user won't see stuff flashing 
     self.Freeze() 

     # (For Mac) Setup a panel 
     self.panel = wx.Panel(self,size=(480,320)) 
     self.panel.SetBackgroundColour(wx.Colour(0,0,128)) 

     # Setup sizer for vertical centering 
     self.sizer = wx.BoxSizer(wx.HORIZONTAL) 

     # Create text field 
     self.txtField = wx.StaticText(self.panel,size=(448,-1),style=wx.ALIGN_CENTRE_HORIZONTAL) 
     self.txtField.SetLabel(text) 
     self.txtField.Wrap(448) 
     self.txtField.SetLabel(self.txtField.GetLabel()) 
     self.txtField.SetFont(wx.Font(36, wx.DEFAULT, wx.BOLD, 0))  
     self.txtField.SetForegroundColour(wx.Colour(255,255,255)) 

     # Add the static text to the sizer 
     self.sizer.Add(self.txtField,1, 0,15) 
     self.panel.SetSizer(self.sizer) 

     # Ensure layouts are applied 
     self.sizer.Layout() 

     # Thaw UI 
     self.Thaw() 

     # Center form 
     self.Center() 

app = wx.App(False) 

c = DisplayText(None, text="Now is the time for all good men to come to the aid of their country.") 
c.Show() 
import wx.lib.inspection 
wx.lib.inspection.InspectionTool().Show() 
app.MainLoop() 

根據我的靜態文本的理解,這個問題似乎是,當我致電Wrap()功能,控制包裝了文本,但不改變控件的大小。這意味着sizer不知道包裝文本的實際垂直尺寸,無法正確地重新定位靜態文本。

我發現一篇文章建議使用wx.EXPAND,但這並不能解決問題。允許sizer擴展StaticText只需使StaticText填充整個框架,並且由於StaticText不垂直居中,文本將最終位於表單的頂部,而不是中心。

另一篇文章建議在sizer中使用wx.ALIGN_CENTER_VERTICAL進行實驗,但這也沒有幫助,因爲同樣的問題仍然存在 - sizer只能處理控件的大小,並且控件的大小不會在更改後文本被包裝並重新渲染。

不同的嘗試導致文本被包裝,但在窗體的頂部,只有第一行顯示在窗體的中心,只有第一行顯示在窗體的頂部,文本沒有被包裹,因此從表單的右側邊緣流出。但是,我所讀過的任何東西的組合都不能將表格上的包裝文本垂直居中。

因此,我必須能夠做的是以某種方式在包裝發生後垂直地確定文本的大小。這是不能假定的,因爲在不同的平臺上,甚至在同一個平臺上,或者甚至基於文本本身,字體的垂直像素大小可能不同。所以這需要以某種方式計算。

我在想,如果我能以某種方式找出StaticText控件中呈現的文本的實際大小,那麼我可以明確地設置控件的大小,然後讓sizer完成它的工作。

這似乎是它應當是在一個相對簡單的事情......

建議將不勝感激!

回答

1

關鍵是靜態文本樣式;您需要爲換行啓用多行樣式:wx.TE_MULTILINE。

我也設置了面板本身的佈局,而不是sizer,但可能與問題無關。

在我的機器上,Windows 7 64bit,我需要更改SetFont調用;您可能需要將其更改回去。

import math 
from threading import Thread 
import time 
import wx 

e = lambda x: complex(math.cos(x), 0) + complex(0, math.sin(x)) 
r = lambda x: ((e(0*math.pi/3.0)*e(x)).real + 1)/2.0 
g = lambda x: ((e(2*math.pi/3.0)*e(x)).real + 1)/2.0 
b = lambda x: ((e(4*math.pi/3.0)*e(x)).real + 1)/2.0 
colo = lambda rad: map(lambda x: int(128 * x(rad)), [r, g, b]) 

class DisplayText(wx.Dialog): 

    def __init__(self, parent, text="", displayMode=0): 

     # Initialize dialog 
     wx.Dialog.__init__(self, parent, size=(480, 320), style=(wx.DIALOG_EX_METAL | wx.STAY_ON_TOP)) 

     # Freeze UI so user won't see stuff flashing 
     self.Freeze() 

     # (For Mac) Setup a panel 
     self.panel = wx.Panel(self, size=(480, 320)) 
     self.panel.SetBackgroundColour(wx.Colour(0, 0, 128)) 
     self.panel.SetBackgroundColour(wx.Colour(*colo(0))) 

     # Setup sizer for vertical centering 
     self.sizer = wx.BoxSizer(wx.HORIZONTAL) 
     self.panel.SetSizer(self.sizer) 

     # Create text field 
     self.txtField = wx.StaticText(self.panel, size=(448, -1), style=(wx.ALIGN_CENTRE_HORIZONTAL | wx.TE_MULTILINE)) 
     self.txtField.SetFont(wx.Font(36, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))  
     self.txtField.SetForegroundColour(wx.Colour(255, 255, 255)) 
     self.txtField.SetLabel(text) 
     self.txtField.Wrap(448) 
     self.sizer.Add(self.txtField, 1, 0, 15) 

     # Add the static text to the sizer 
     # Ensure layouts are applied 
     self.panel.Layout() 
     self.panel.Refresh() 

     # Thaw UI 
     self.Thaw() 

     # Center form 
     self.Center() 

     self.angle = 0 
     self.angle_inc = (2*math.pi)/25.0 

    def change_colour(self): 
     t = Thread(target=self.epilepsy_mode) 
     t.start() 

    def epilepsy_mode(self): 
     while True: 
      time.sleep(0.02) 
      self.panel.SetBackgroundColour(wx.Colour(*colo(self.angle))) 
      self.panel.Refresh() 
      self.angle = (self.angle + self.angle_inc) % (2*math.pi) 

app = wx.App(False) 

c = DisplayText(None, text="Now is the time for all good men to come to the aid of their country.") 
c.Show() 
#import wx.lib.inspection 
#wx.lib.inspection.InspectionTool().Show() 
c.change_colour() 

app.MainLoop()