wxPython工具包提供了多种不同的窗口部件,包括了本章所提到的基本控件。我们涉及静态文本、可编辑的文本、按钮、微调、滑块、复选框、单选按钮、选择器、列表框、组合框和标尺。对于每种窗口部件,我们将提供一个关于如何使用它的简短例子,并附上相关的wxPython API的说明。

 

显示文本

这一节以在屏幕上显示文本的例子作为开始,包括用作标签的静态文本域,有样式和无样式的都使用了。你可以创建用于用户输入的单行和多行文本域。另外,我们将讨论如何选择文本的字体。

 

如何显示静态文本?

大概对于所有的UI工具来说,最基本的任务就是在屏幕上绘制纯文本。在wxPython中,使用类wx.StaticText来完成。图7.1显示了这个静态文本控件。

在wx.StaticText中,你能够改变文本的对齐方式、字体和颜色。简单的静态文本控件可以包含多行文本,但是你不能处理多种字体或样式。处理多种字体或样式,要使用更精细的文本控件,如wx.html.HTMLWindow,它在第十六章中说明。为了在静态文本控件中显示多行文本,我们要包括其中有换行符的字符串,并使控件的大小足够显示所有的文本。有一个特点是你在图7.1中所不能看到的,那就是wx.StaticText窗口不会接受或响应鼠标事件。

如何显示静态文本

例子7.1显示了产生图7.1的代码。

例7.1 如何使用静态文本的一个基本例子

#coding=utf-8
import wx
class StaticTextFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None,-1,'my StaticTextFrame',(0,0),(400,300))

# Panel是窗口的容器,通常其大小与Frame一样,在其上放置各种控件,
# 这样可将窗口内容与工具栏及状态栏区分开,能过TAB键可遍历Panel中的元素
# 因为panel覆盖在Frame之上,Frame初始化方法中有self,属于实例对象,故panel也应该属于实例,使用self修饰
        panel = wx.Panel(self,-1)

# 生成一个基本的静态文本
        wx.StaticText(panel,-1,'StaticText',(100,10))

# 指定前景色、背景色的静态文本
        rev = wx.StaticText(panel,-1,'Static Text with reversed colors',(100,30))
        rev.SetForegroundColour('white')
        rev.SetBackgroundColour('black')

# 指定居中对齐的静态文本
        center = wx.StaticText(panel,-1,'align center',(100,50),(160,-1),wx.ALIGN_CENTER)
        center.SetForegroundColour('white')
        center.SetBackgroundColour('black')

# 指定右对齐的静态文本
        right = wx.StaticText(panel,-1,'align right',(100,70),(160,-1),wx.ALIGN_RIGHT)
        right.SetForegroundColour('white')
        right.SetBackgroundColour('black')

# 指定新字体的静态文本
        str1 = "You can also change the font."
        text = wx.StaticText(panel,-1,str1,(20,100))
        font = wx.Font(18,wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
        text.SetFont(font)

# 显示多行文本
        wx.StaticText(panel,-1,"Your text\ncan be split\n"
            "over multiple lines\n\neven blank ones",(20,150))

# 显示对齐的多行文本
        wx.StaticText(panel, -1, "Multi-line text\ncan also\n"
                "be right aligned\n\neven with a blank", (220,150), 
                style=wx.ALIGN_RIGHT)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = StaticTextFrame()
    frame.Show()
    app.MainLoop()

wx.StaticText的构造函数和基本的wxWidget构造函数相同,如下所示:

Toggle line numbers

1 wx.StaticText(parent, id, label, pos=wx.DefaultPosition,
   2 size=wx.DefaultSize, style=0, name="staticText")

表7.1说明了这些参数——大多数的wxPython窗口部件都有相类似的参数。对于构造函数的参数的更详细的说明,请参见第2章的相关论述。

表7.1 wx.StaticText构造函数的参数

parent:父窗口部件。

id:标识符。使用-1可以自动创建一个唯一的标识。

label:你想显示在静态控件中的文本。

pos:一个wx.Point或一个Python元组,它是窗口部件的位置。

size:一个wx.Size或一个Python元组,它是窗口部件的尺寸。

style:样式标记。

name:对象的名字,用于查找的需要。

接下来我们更详细地讨论样式标记。

使用样式工作

所有在例7.1中静态文本实例所调用的方法都是属于基父类wx.Window的;wx.StaticText没有定义任何它自己的新方法。表7.2列出了一些专用于wx.StaticText的样式。

表7.2

wx.ALIGN_CENTER:静态文本位于静态文本控件的中心。

wx.ALIGN_LEFT:文本在窗口部件中左对齐。这是默认的样式。

wx.ALIGN_RIGHT:文本在窗口部件中右对齐。

wx.ST_NO_AUTORESIZE:如果使用了这个样式,那么在使用了SetLabel()改变文本之后,静态文本控件不将自我调整尺寸。你应结合使用一个居中或右对齐的控件来保持对齐。

wx.StaticText控件覆盖了SetLabel(),以便根据新的文本来调整自身,除非wx.ST_NO_AUTORESIZE样式被设置了。

当创建了一个居中或右对齐的单行静态文本时,你应该显式地在构造器中设置控件的尺寸。指定尺寸以防止wxPython自动调整该控件的尺寸。wxPython的默认尺寸是刚好包容了文本的矩形尺寸,因此对齐就没有什么必要。要在程序中动态地改变窗口部件中的文本,而不改变该窗口部件的尺寸,就要设置wx.ST_NO_AUTORESIZE样式。这样就防止了在文本被重置后,窗口部件自动调整尺寸到刚好包容了文本。如果静态文本是位于一个动态的布局中,那么改变它的尺寸可能导致屏幕上其它的窗口部件移动,这就对用户产生了干扰。

其它显示文本的技术

还有其它的方法来显示文本。其中之一就是wx.lib.stattext.GenStaticText类,它是wx.StaticText的纯Python实现。它比标准C++版的跨平台性更好,并且它接受鼠标事件。当你想子类化或创建你自己的静态文本控件时,它是更可取的。

你可以使用DrawText(text, x,y)和DrawRotatedText(text, x, y, angle)方法直接绘制文本到你的设备上下文。后者是显示有一定角度的文本的最容易的方法,尽管GenStaticText的子类也能处理旋转问题。设备上下文在第6章中做了简短的说明,我们将在第12章中对它做更详细的说明。

 

如何让用户输入文本?

超越纯粹显示静态文本,我们将开始讨论当输入文本时的用户交互。wxPython的文本域窗口部件的类是wx.TextCtrl,它允许单行和多行文本输入。它也可以作为密码输入控件,掩饰所按下的按键。如果平台支持的话,wx.TextCtrl也提供丰富格式文本的显示,通过使用所定义和显示的多文本样式。图7.2显示了一个作为单行控件的wx.TextCtrl的样板。其中的密码输入框对密码进行了掩饰。

接下来,我们将演示如何创建文本,然后讨论文本控件的样式选项。

如何创建文本输入控件

例子7.2显示了用于生成图7.2的代码

例7.2 wx.TextCtrl的单行例子

#coding=utf-8
import wx

class TextFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Text Entry Example', 
                size=(300, 100))
        panel = wx.Panel(self, -1) 
        basicLabel = wx.StaticText(panel, -1, "Basic Control:")
        basicText = wx.TextCtrl(panel, -1, "I've entered some text!", 
                size=(175, -1),style = wx.TE_NOHIDESEL)
        basicText.SetInsertionPoint(0)

        pwdLabel = wx.StaticText(panel, -1, "Password:")
        pwdText = wx.TextCtrl(panel, -1, "password", size=(175, -1), 
                style=wx.TE_PASSWORD)
        sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
        sizer.AddMany([basicLabel, basicText, pwdLabel, pwdText])
        panel.SetSizer(sizer)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = TextFrame()
    frame.Show()
    app.MainLoop()

  

wx.TextCtrl类的构造函数较小且比其父类wx.Window更精细,它增加了两个参数:

wx.TextCtrl(parent, id, value = "", pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, validator=wx.DefaultValidator name=wx.TextCtrlNameStr)

参数parent, id, pos, size, style, 和 name与wx.Window构造函数的相同。value是显示在该控件中的初始文本。

validator参数用于一个wx.Validator。validator通常用于过虑数据以确保只能键入要接受的数据。将在第9章对validator做更详细的讨论。

使用单行文本控件样式

这里,我们将讨论一些唯一无二的文本控件样式。 表7.3说明了用于单行文本控件的样式标记

表7.3 单行wx.TextCtrl的样式

wx.TE_CENTER:控件中的文本居中。

wx.TE_LEFT:控件中的文本左对齐。默认行为。

wx.TE_NOHIDESEL:文本始终高亮显示,只适用于Windows。

wx.TE_PASSWORD:不显示所键入的文本,代替以星号显示。

wx.TE_PROCESS_ENTER:如果使用了这个样式,那么当用户在控件内按下回车键时,一个文本输入事件被触发。否则,按键事件内在的由该文本控件或该对话框管理。

wx.TE_PROCESS_TAB:如果指定了这个样式,那么通常的字符事件在Tab键按下时创建(一般意味一个制表符将被插入文本)。否则,tab由对话框来管理,通常是控件间的切换。

wx.TE_READONLY:文本控件为只读,用户不能修改其中的文本。

wx.TE_RIGHT:控件中的文本右对齐。

像其它样式标记一样,它们可以使用|符号来组合使用,尽管其中的三个对齐标记是相互排斥的。

对于添加文本和移动插入点,该文本控件自动管理用户的按键和鼠标事件。对于该文本控件可用的命令控制组合说明如下:

  • ctrl-x :剪切 ctrl-c :复制 ctrl-v :粘贴 ctrl-z :撤消

 

不输入的情况下如何改变文本?

除了根据用户的输入改变显示的文本外,wx.TextCtrl提供了在程序中改变显示的文本的一些方法。你可以完全改变文本或仅移动插入点到文本中不同的位置。表7.4列出了wx.TextCtrl的文本处理方法。

表7.4

AppendText(text):在尾部添加文本。

Clear():重置控件中的文本为“”。并且生成一个文本更新事件。

EmulateKeyPress(event):产生一个按键事件,插入与事件相关联的控制符,就如同实际的按键发生了。

GetInsertionPoint() SetInsertionPoint(pos) SetInsertionPointEnd():得到或设置插入点的位置,位置是整型的索引值。控件的开始位置是0。

GetRange(from, to):返回控件中位置索引范围内的字符串。

GetSelection() GetStringSelection() SetSelection(from, to):GetSelection()以元组的形式返回当前所选择的文本的起始位置的索引值(开始,结束)。GetStringSelection()得到所选择的字符串。SetSelection(from, to)设置选择的文本。

GetValue() SetValue(value):SetValue()改变控件中的全部文本。GetValue()返回控件中所有的字符串。

Remove(from, to):删除指定范围的文本。

Replace(from, to, value):用给定的值替换掉指定范围内的文本。这可以改变文本的长度。

WriteText(text):类似于AppendText(),只是写入的文本被放置在当前的插入点。

当你的控件是只读的或如果你根据事件而非用户键盘输入来改变控件中的文本是,这些方法是十分有用的。

 

如何创建一个多行或样式文本控件?

你可以使用wx.TE_MULTILINE样式标记创建一个多行文本控件。如果本地窗口控件支持样式,那么你可以改变被控件管理的文本的字体和颜色样式,这有时被称为丰富格式文本。对于另外的一些平台,设置样式的调用被忽视掉了。图7.3显示了多行文本控件的一个例子。

例7.3包含了用于创建图7.3的代码。通常,创建一个多行文本控件是通过设置wx.TE_MULTILINE样式标记来处理的。较后的部分,我们将讨论使用丰富文本样式。

例7.3 创建一个多行文本控件

Toggle line numbers

1 import wx
   2 
   3 class TextFrame(wx.Frame):
   4 
   5     def __init__(self):
   6         wx.Frame.__init__(self, None, -1, 'Text Entry Example', 
   7                 size=(300, 250))
   8         panel = wx.Panel(self, -1) 
   9         multiLabel = wx.StaticText(panel, -1, "Multi-line")
  10         multiText = wx.TextCtrl(panel, -1,
  11                "Here is a looooooooooooooong line of text set in the control.\n\n"
  12                "See that it wrapped, and that this line is after a blank",
  13                size=(200, 100), style=wx.TE_MULTILINE) #创建一个文本控件
  14         multiText.SetInsertionPoint(0) #设置插入点
  15 
  16         richLabel = wx.StaticText(panel, -1, "Rich Text")
  17         richText = wx.TextCtrl(panel, -1, 
  18                 "If supported by the native control, this is reversed, and this is a different font.",
  19                 size=(200, 100), style=wx.TE_MULTILINE|wx.TE_RICH2) #创建丰富文本控件
  20         richText.SetInsertionPoint(0)
  21         richText.SetStyle(44, 52, wx.TextAttr("white", "black")) #设置文本样式
  22         points = richText.GetFont().GetPointSize() 
  23         f = wx.Font(points + 3, wx.ROMAN, wx.ITALIC, wx.BOLD, True) #创建一个字体
  24         richText.SetStyle(68, 82, wx.TextAttr("blue", wx.NullColour, f)) #用新字体设置样式
  25         sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
  26