2

我在互联网上看到了很多关于此的帖子,但没有一个建议有效。

这是我的测试代码:

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()

根据我对 StaticText 的理解,问题似乎是当我调用该Wrap()函数时,控件会换行文本但不会更改控件的大小。这意味着 sizer 不知道换行文本的实际垂直大小,无法正确重新定位静态文本。

我发现一篇帖子建议使用 wx.EXPAND,但这并不能解决问题。允许 sizer 扩展 StaticText 只会使 StaticText 填充整个框架,并且由于 StaticText 本身不会垂直居中,因此文本将最终位于表单的顶部,而不是中心。

另一篇文章建议在 sizer 中尝试 wx.ALIGN_CENTER_VERTICAL,但这也无济于事,因为同样的问题仍然存在 - sizer 只能在控件的大小上起作用,并且控件的大小在文本被换行后不会改变并重新渲染。

各种尝试导致文本被包裹但在表单的顶部,只有第一行显示在表单的中心,只有第一行显示在表单的顶部,并且文本没有被包裹并且因此从表格的右侧边缘流出。但是,我读过的任何内容都无法将包装的文本垂直居中放置在表单上。

因此,我必须能够以某种方式在换行后垂直计算文本的大小。这是不能假设的,因为在不同的平台上,甚至在同一个平台上,甚至基于文本本身,字体的垂直像素大小可能会有所不同。所以这需要以某种方式计算。

我在想,如果我能以某种方式找出 StaticText 控件中呈现文本的实际大小,然后我可以显式设置控件的大小,然后让 sizer 完成它的工作。

这似乎应该是一件相对简单的事情来完成......

建议将不胜感激!

4

1 回答 1

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()
于 2013-07-23T04:32:08.907 回答