wxPython - 快速指南
wxPython - Introduction
wxPython是wxWidgets (用C ++编写)的Python包装器,是一种流行的跨平台GUI工具包。 由Robin Dunn和Harri Pasanen共同开发,wxPython作为Python扩展模块实现。
就像wxWidgets一样,wxPython也是一款免费软件。 它可以从官方网站http://wxpython.org.下载http://wxpython.org. 许多操作系统平台的二进制文件和源代码可在此站点上下载。
wxPython API中的主要模块包括核心模块。 它由wxObject类组成,它是API中所有类的基础。 控制模块包含GUI应用程序开发中使用的所有小部件。 例如,wx.Button,wx.StaticText(类似于标签),wx.TextCtrl(可编辑文本控件)等。
wxPython API具有GDI(图形设备接口)模块。 它是一组用于绘制小部件的类。 字体,颜色,画笔等类是其中的一部分。 所有容器窗口类都在Windows模块中定义。
wxPython的官方网站还托管Project Phoenix - 一个用于Python 3 *的wxPython的新实现。 它侧重于提高速度,可维护性和可扩展性。 该项目始于2012年,目前仍处于测试阶段。
wxPython - Environment
Windows
Windows操作系统的预构建二进制文件(32位和64位)可在http://www.wxpython.org/download.php页面上http://www.wxpython.org/download.php 。 最新版本的安装程序是 - 用于32位Python的wxPython3.0-win64-3.0.2.0-py27.exe用于64位Python 2.7的wxPython3.0-win64-3.0.2.0-py27.exe
wxPython演示,示例和wxWidgets文档也可以在同一页面上下载。
wxPython3.0-win32-docs-demos.exe
Linux
许多Linux发行版的wxPython二进制文件可以在各自的存储库中找到。 必须使用相应的包管理器进行下载和安装。 例如在Debian Linux上,以下命令应该能够安装wxPython。
sudo apt-get install python-wxgtk3.0
MacOS
在官方网站的下载页面上提供了以磁盘映像形式的MacOS预构建二进制文件。
wxPython - Hello World
显示Hello World消息的简单GUI应用程序使用以下步骤构建 -
导入wx模块。
定义Application类的对象。
创建一个顶级窗口作为wx.Frame类的对象。 标题和大小参数在构造函数中给出。
虽然可以在Frame对象中添加其他控件,但无法管理其布局。 因此,将Panel对象放入Frame中。
添加一个StaticText对象,在窗口内的所需位置显示“Hello World”。
通过show()方法激活框架窗口。
输入Application对象的主事件循环。
import wx
app = wx.App()
window = wx.Frame(None, title = "wxPython Frame", size = (300,200))
panel = wx.Panel(window)
label = wx.StaticText(panel, label = "Hello World", pos = (100,50))
window.Show(True)
app.MainLoop()
上面的代码产生以下输出 -
wxFrame object是最常用的顶级窗口。 它源自wxWindow class 。 框架是一个窗口,其大小和位置可以由用户改变。 它有一个标题栏和控制按钮。 如果需要,可以启用菜单栏,工具栏和状态栏等其他组件。 wxFrame窗口可以包含任何不是对话框或其他框架的框架。
wxPython - GUI Builder Tools
通过手动编码创建美观的GUI可能很乏味。 可视化GUI设计器工具总是很方便。 许多针对wxPython的GUI开发IDE都可用。 以下是其中一些 -
- wxFormBuilder
- wxDesigner
- wxGlade
- BoaConstructor
- gui2py
wxFormBuilder是一个开源的,跨平台的WYSIWYG GUI构建器,可以将wxWidget GUI设计转换为C ++,Python,PHP或XML格式。 这里给出了wxFormBuilder用法的简要介绍。
首先,需要从http://sourceforge.net/projects/wxformbuilder/.下载并安装最新版本的wxFormBuilder http://sourceforge.net/projects/wxformbuilder/. 打开应用程序时,将出现一个中心为空白灰色区域的新项目。
为项目指定一个合适的名称,并选择Python作为代码生成语言。 这在对象属性窗口中完成,如下图所示 -
然后从组件面板的“表单”选项卡中选择“帧”。
从“布局”选项卡添加垂直wxBoxSizer。
使用合适的标题在Box中添加必要的控件。 这里添加了一个StaticText(标签),两个TextCtrl对象(文本框)和一个wxButton对象。 框架如下图所示 -
在这三个控件上启用“展开”和“拉伸”。 在wxButton对象的对象属性中,将函数findsquare()分配给OnButtonClick事件。
保存项目并按F8为开发的GUI生成Python代码。 让生成的文件命名为Demo.py
在可执行的Python脚本中,导入demo.py并定义FindSquare()函数。 声明Application对象并启动主事件循环。 以下是可执行代码 -
import wx
#import the newly created GUI file
import demo
class CalcFrame(demo.MyFrame1):
def __init__(self,parent):
demo.MyFrame1.__init__(self,parent)
def FindSquare(self,event):
num = int(self.m_textCtrl1.GetValue())
self.m_textCtrl2.SetValue (str(num*num))
app = wx.App(False)
frame = CalcFrame(None)
frame.Show(True)
#start the applications
app.MainLoop()
上面的代码产生以下输出 -
wxPython - Major Classes
原始的wxWidgets(用C ++编写)是一个庞大的类库。 此库中的GUI类使用wxPython模块移植到Python,该模块尝试尽可能接近镜像原始wxWidgets库。 因此,wxPython中的wx.Frame类与其C ++版本中的wxFrame类的行为方式大致相同。
wxObject是大多数类的基础。 wxApp的对象(wxPython中的wx.App)表示应用程序本身。 生成GUI后,应用程序通过MainLoop()方法进入事件循环。 下图描绘了wxPython中包含的最常用GUI类的类层次结构。
SN | 课程和描述 |
---|---|
1 | wx.Frame wx.Frame类有一个没有参数的默认构造函数。 |
2 | wx.Panel wx.Panel类通常放在wxFrame对象中。 该类也继承自wxWindow类。 |
3 | wx.StaticText wx.StaticText类对象提供了一个包含此类只读文本的控件。 它可以被称为被动控制,因为它不会产生任何事件。 |
4 | TextCtrl 在wxPython中,wx.TextCtrl类的对象用于此目的。 它是一个可以显示和编辑文本的控件。 |
5 | RadioButton&RadioBox 每个按钮,wx.RadioButton类的对象在圆形按钮旁边都有一个文本标签。 wxPython API也包含wx.RadioBox类。 它的对象为组提供边框和标签。 |
6 | wx.CheckBox 复选框显示一个带标签的小方框。 单击时,矩形内会出现一个复选标记,表示已做出选择。 |
7 | ComboBox和选择类 wx.ComboBox对象提供了可供选择的项列表。 它可以配置为下拉列表或永久显示。 wxPython API包含一个wx.Choice类,其对象也是一个永久只读的下拉列表。 |
8 | Wx.Gauge Wx.Gauge类对象显示垂直或水平条,以图形方式显示递增数量。 |
9 | wx.Slider wxPython API包含wx.Slider类。 它提供与滚动条相同的功能。 Slider提供了一种方便的方法来处理特定于滑块的wx.EVT_SLIDER事件绑定器拖动句柄。 |
10 | wx.MenuBar 顶级窗口标题栏正下方的水平栏保留显示一系列菜单。 它是wxPython API中wx.MenuBar类的对象。 |
11 | wx.Toolbar 如果wx.Toolbar对象的style参数设置为wx.TB_DOCKABLE,则它变为可停靠。 也可以使用wxPython的AUIToolBar类构建浮动工具栏。 |
12 | Wx.Dialog 尽管Dialog类对象看起来像Frame,但它通常用作父框架顶部的弹出窗口。 Dialog的目标是从用户收集一些数据并将其发送到父框架。 |
13 | wx.Notebook wx.Notebook小部件提供了一个选项卡式控件。 框架中的一个Notebook对象具有一个或多个选项卡(称为页面),每个选项卡都有一个显示控件布局的面板。 |
14 | wx.SplitterWindow 此类的对象是布局管理器,它包含两个子窗口,其大小可以通过拖动它们之间的边界来动态更改。 Splitter控件提供了一个可以拖动以调整控件大小的句柄。 |
15 | HTMLWindow wxHTML库包含用于解析和显示HTML内容的类。 虽然这不是一个功能齐全的浏览器,但wx.HtmlWindow对象是一个通用的HTML查看器。 |
16 | ListBox和ListCtrl wx.ListBox小部件呈现可垂直滚动的字符串列表。 默认情况下,列表中的单个项目是可选的。 ListCtrl小部件是一个高度增强的列表显示和选择工具。 可以在“报表”视图,“列表”视图或“图标”视图中显示多个列的列表。 |
wxPython - Event Handling
与以顺序方式执行的控制台模式应用程序不同,基于GUI的应用程序是事件驱动的。 执行函数或方法以响应用户的操作,例如单击按钮,从集合中选择项目或鼠标单击等,称为事件。
与应用程序运行时期间发生的事件有关的数据存储为从wx.Event派生的子类的对象。 显示控件(如Button)是特定类型的事件源,并生成与其关联的Event类的对象。 例如,单击按钮会发出wx.CommandEvent。 此事件数据被分派到程序中的事件处理程序方法。 wxPython有许多预定义的事件绑定器。 Event binder封装了特定小部件(控件),其关联的事件类型和事件处理程序方法之间的关系。
例如,要在按钮的单击事件上调用程序的OnClick() method ,需要以下语句 -
self.b1.Bind(EVT_BUTTON, OnClick)
Bind() method由来自wx.EvtHandler类的所有显示对象继承。 EVT_.BUTTON这里是绑定器,它将按钮单击事件与OnClick()方法相关联。
例子 (Example)
在下面的示例中,通过拖动顶层窗口(在本例中为wx.Frame对象OnMove() method导致的OnMove() method使用wx.EVT_MOVE绑定器连接到OnMove() method 。 代码显示一个窗口。 如果使用鼠标移动它,它的瞬时坐标将显示在控制台上。
import wx
class Example(wx.Frame):
def __init__(self, *args, **kw):
super(Example, self).__init__(*args, **kw)
self.InitUI()
def InitUI(self):
self.Bind(wx.EVT_MOVE, self.OnMove)
self.SetSize((250, 180))
self.SetTitle('Move event')
self.Centre()
self.Show(True)
def OnMove(self, e):
x, y = e.GetPosition()
print "current window position x = ",x," y= ",y
ex = wx.App()
Example(None)
ex.MainLoop()
上面的代码产生以下输出 -
当前窗口位置x = 562 y = 309
当前窗口位置x = 562 y = 309
当前窗口位置x = 326 y = 304
当前窗口位置x = 384 y = 240
当前窗口位置x = 173 y = 408
当前窗口位置x = 226 y = 30
当前窗口位置x = 481 y = 80
从wx.Event继承的一些子类列在下表中 -
SN | 活动和描述 |
---|---|
1 | wxKeyEvent 按下或释放按键时发生 |
2 | wxPaintEvent 每当窗口的内容需要重绘时生成 |
3 | wxMouseEvent 包含有关鼠标活动(如按下或拖动鼠标按钮)导致的任何事件的数据 |
4 | wxScrollEvent 与可滚动控件相关联,如wxScrollbar和wxSlider |
5 | wxCommandEvent 包含源自许多小部件的事件数据,如按钮,对话框,剪贴板等。 |
6 | wxMenuEvent 不同的菜单相关事件,不包括菜单命令按钮单击 |
7 | wxColourPickerEvent wxColourPickerCtrl生成的事件 |
8 | wxDirFilePickerEvent FileDialog和DirDialog生成的事件 |
wxPython中的事件有两种类型。 基本事件和命令事件。 基本事件保持在其发起的窗口的本地。 大多数wxWidgets都会生成命令事件。 command event可以传播到窗口或窗口,窗口或窗口位于类层次结构中的源窗口之上。
例子 (Example)
以下是事件传播的简单示例。 完整的代码是 -
import wx
class MyPanel(wx.Panel):
def __init__(self, parent):
super(MyPanel, self).__init__(parent)
b = wx.Button(self, label = 'Btn', pos = (100,100))
b.Bind(wx.EVT_BUTTON, self.btnclk)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
def OnButtonClicked(self, e):
print 'Panel received click event. propagated to Frame class'
e.Skip()
def btnclk(self,e):
print "Button received click event. propagated to Panel class"
e.Skip()
class Example(wx.Frame):
def __init__(self,parent):
super(Example, self).__init__(parent)
self.InitUI()
def InitUI(self):
mpnl = MyPanel(self)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
self.SetTitle('Event propagation demo')
self.Centre()
self.Show(True)
def OnButtonClicked(self, e):
print 'click event received by frame class'
e.Skip()
ex = wx.App()
Example(None)
ex.MainLoop()
在上面的代码中,有两个类。 MyPanel ,一个wx.Panel子类和Example,一个wx.Frame子类,它是程序的顶级窗口。 按钮放置在面板中。
此Button对象绑定到事件处理程序btnclk(),该事件处理程序将其传播到父类(在本例中为MyPanel)。 按钮单击生成一个CommandEvent ,可以通过Skip()方法将其传播到其父级。
MyPanel类对象还将接收到的事件绑定到另一个处理程序OnButtonClicked()。 该函数依次传输给它的父类Example类。 上面的代码产生以下输出 -
Button received click event. Propagated to Panel class.
Panel received click event. Propagated to Frame class.
Click event received by frame class.
wxPython - Layout Management
通过指定以像素为单位测量的绝对坐标,可以将GUI小部件放置在容器窗口内。 坐标相对于由其构造函数的size参数定义的窗口的尺寸。 窗口小部件在窗口内的位置由其构造函数的pos参数定义。
import wx
app = wx.App()
window = wx.Frame(None, title = "wxPython Frame", size = (300,200))
panel = wx.Panel(window)
label = wx.StaticText(panel, label = "Hello World", pos = (100,50))
window.Show(True)
app.MainLoop()
然而,由于以下原因,这种Absolute Positioning不合适 -
即使调整窗口大小,窗口小部件的位置也不会改变。
在具有不同分辨率的不同显示设备上外观可能不均匀。
布局中的修改很困难,因为它可能需要重新设计整个表单。
wxPython API提供了布局类,可以更加优雅地管理容器内小部件的定位。 布局管理者优于绝对定位的优势是 -
- 窗口内的窗口小部件会自动调整大小。
- 确保在具有不同分辨率的显示设备上均匀外观。
- 无需重新设计即可动态添加或删除小部件。
布局管理器在wxPython中称为Sizer。 Wx.Sizer是所有sizer子类的基类。 让我们讨论一些重要的大小调整器,如wx.BoxSizer,wx.StaticBoxSizer,wx.GridSizer,wx.FlexGridSizer和wx.GridBagSizer。
SN | Sizer和描述 |
---|---|
1 | BoxSizer 该分级器允许控件以行方式或列方式排列。 BoxSizer的布局由其方向参数(wxVERTICAL或wxHORIZONTAL)决定。 |
2 | GridSizer 顾名思义,GridSizer对象呈现二维网格。 控件以从左到右和从上到下的顺序添加到网格槽中。 |
3 | FlexiGridSizer 该分级器还具有二维网格。 然而,它在细胞中布置对照物时提供了更多的灵活性。 |
4 | GridBagSizer GridBagSizer是一款多功能的分级器。 它提供了比FlexiGridSizer更多的增强功能。 子窗口小部件可以添加到网格中的特定单元格。 |
5 | StaticBoxSizer StaticBoxSizer将box sizer放入静态框中。 它提供了盒子周围的边框以及顶部的标签。 |
wxPython - Buttons
Button小部件在任何GUI界面中使用最为广泛。 它捕获用户生成的单击事件。 它最明显的用途是触发绑定到它的处理函数。
wxPython类库提供了不同类型的按钮。 有一个简单的传统按钮, wx.Button类对象,它带有一些文本作为标题。 还提供了一个双状态按钮,名为wx.ToggleButton 。 可以通过事件处理程序功能识别其按下或按下状态。
另一种类型的按钮wx.BitmapButton在其面上显示位图(图像)作为图标。
wx.Button类和wx.ToggleButton类的构造函数采用以下参数 -
Wx.Button(parent, id, label, pos, size, style)
这些是wx.Button类的一些重要方法 -
SN | 方法和描述 |
---|---|
1 | SetLabel() 以编程方式设置按钮的标题 |
2 | GetLabel() 返回按钮的标题 |
3 | SetDefault() 顶级窗口的按钮设置为默认值。 按Enter键模拟单击事件 |
wx.ToggleButton类的两个重要方法是 -
SN | 方法和描述 |
---|---|
1 | GetValue() 返回切换按钮的状态(开/关) |
2 | SetValue() 以编程方式设置按钮的状态 |
为了创建位图按钮,首先,需要从图像文件构造位图对象。
wx.Bitmap类构造函数的以下变体是最常用的 -
Wx.Bitmap(fiiename, wx.BITMAP_TYPE)
一些预定义的位图类型常量是 -
wx.BITMAP_TYPE_BMP |
wx.BITMAP_TYPE_ICO |
wx.BITMAP_TYPE_CUR |
wx.BITMAP_TYPE_TIFF |
wx.BITMAP_TYPE_TIF |
wx.BITMAP_TYPE_GIF |
wx.BITMAP_TYPE_PNG |
wx.BITMAP_TYPE_JPEG |
wx.BITMAP_TYPE_PCX |
wx.BITMAP_TYPE_ICON |
wx.BITMAP_TYPE_ANY |
此位图对象用作wx.BitmapButton类构造函数的参数之一。
Wx.BitmapButton(parent, id, bitmap, pos, size, style)
在某些OS平台上,位图按钮可以显示位图和标签。 SetLabel()方法分配标题。 在其他平台上,它作为内部标签。
普通按钮以及位图按钮会发出wx.CommandEvent。 EVT_BUTTON binder将处理函数与其关联。
另一方面,切换按钮使用wx.TOGGLEBUTTON活页夹进行事件处理。
在以下示例中,所有三种类型的按钮都放置在面板的垂直框大小调整器中。
使用语句创建简单按钮对象 -
self.btn = wx.Button(panel, -1, "click Me")
切换按钮由以下声明构成 -
self.tbtn = wx.ToggleButton(panel , -1, "click to on")
使用以下语句将这些按钮添加到垂直sizer中 -
vbox.Add(self.btn,0,wx.ALIGN_CENTER)
vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER)
Note - 由于wx.EXPAND标志,切换按钮占据框架的整个宽度。
使用EVT_BUTTON和EVT_TOGGLEBUTTON绑定器,它们与相应的处理程序相关联。
self.btn.Bind(wx.EVT_BUTTON,self.OnClicked)
self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)
三个位图按钮被添加到水平框大小调整器中。 这些按钮将图像显示为图标作为其标题。
bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
这三个按钮的Click事件被定向到OnClicked()方法。
self.bmpbtn.Bind(wx.EVT_BUTTON, self.OnClicked)
self.bmpbtn1.Bind(wx.EVT_BUTTON, self.OnClicked)
self.bmpbtn2.Bind(wx.EVT_BUTTON, self.OnClicked)
这些按钮的内部标签分别设置为NEW,OPEN和SAVE。
OnClicked()事件处理函数检索源按钮的标签,这会导致click事件。 该标签印在控制台上。
def OnClicked(self, event):
btn = event.GetEventObject().GetLabel()
print "Label of pressed button = ",btn
单击切换按钮时会触发OnToggle()事件处理程序。 它的状态由GetValue()方法读取,因此,按钮的标题已设置。
def OnToggle(self,event):
state = event.GetEventObject().GetValue()
if state == True:
print "off"
event.GetEventObject().SetLabel("click to off")
else:
print "on"
event.GetEventObject().SetLabel("click to on")
完整的代码清单如下 -
import wx
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title,size = (200,150))
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
self.btn = wx.Button(panel,-1,"click Me")
vbox.Add(self.btn,0,wx.ALIGN_CENTER)
self.btn.Bind(wx.EVT_BUTTON,self.OnClicked)
self.tbtn = wx.ToggleButton(panel , -1, "click to on")
vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER)
self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)
hbox = wx.BoxSizer(wx.HORIZONTAL)
bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
hbox.Add(self.bmpbtn,0,wx.ALIGN_CENTER)
self.bmpbtn.Bind(wx.EVT_BUTTON,self.OnClicked)
self.bmpbtn.SetLabel("NEW")
bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
hbox.Add(self.bmpbtn1,0,wx.ALIGN_CENTER)
self.bmpbtn1.Bind(wx.EVT_BUTTON,self.OnClicked)
self.bmpbtn1.SetLabel("OPEN")
bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
hbox.Add(self.bmpbtn2,0,wx.ALIGN_CENTER)
self.bmpbtn2.Bind(wx.EVT_BUTTON,self.OnClicked)
self.bmpbtn2.SetLabel("SAVE")
vbox.Add(hbox,1,wx.ALIGN_CENTER)
panel.SetSizer(vbox)
self.Centre()
self.Show()
self.Fit()
def OnClicked(self, event):
btn = event.GetEventObject().GetLabel()
print "Label of pressed button = ",btn
def OnToggle(self,event):
state = event.GetEventObject().GetValue()
if state == True:
print "Toggle button state off"
event.GetEventObject().SetLabel("click to off")
else:
print " Toggle button state on"
event.GetEventObject().SetLabel("click to on")
app = wx.App()
Mywin(None, 'Button demo')
app.MainLoop()
上面的代码产生以下输出 -
按下的按钮标签=单击我
切换按钮状态关闭
切换按钮状态
按下的按钮标签=新
按下的按钮标签= OPEN
按下的按钮标签= SAVE
wxPython - Dockable Windows
wxAui是一个包含在wxWidgets API中的高级用户界面库。 Wx.aui.AuiManager是AUI框架中的中心类。
AuiManager使用wx.aui.AuiPanelInfo对象中的每个面板信息管理与特定帧关联的窗格。 让我们了解PanelInfo对象控件对接和浮动行为的各种属性。
将可停靠窗口放在顶层框架中涉及以下步骤 -
首先,创建一个AuiManager对象。
self.mgr = wx.aui.AuiManager(self)
然后,设计具有所需控件的面板。
pnl = wx.Panel(self)
pbox = wx.BoxSizer(wx.HORIZONTAL)
text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE)
pbox.Add(text1, 1, flag = wx.EXPAND)
pnl.SetSizer(pbox)
设置AuiPanelInfo的以下参数。
Direction - 顶部,底部,左侧,右侧或中心
Position - 可以在可停靠区域内放置多个窗格。 每个人都有一个位置编号。
Row - 一行中出现多个窗格。 就像出现在同一行中的多个工具栏一样。
Layer - 窗格可以放置在图层中。
使用此PanelInfo,设计的面板将添加到管理器对象中。
info1 = wx.aui.AuiPaneInfo().Bottom()
self.mgr.AddPane(pnl,info1)
顶级窗口的其余部分可以像往常一样具有其他控件。
完整的代码如下 -
import wx
import wx.aui
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title, size = (300,300))
self.mgr = wx.aui.AuiManager(self)
pnl = wx.Panel(self)
pbox = wx.BoxSizer(wx.HORIZONTAL)
text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE)
pbox.Add(text1, 1, flag = wx.EXPAND)
pnl.SetSizer(pbox)
info1 = wx.aui.AuiPaneInfo().Bottom()
self.mgr.AddPane(pnl, info1)
panel = wx.Panel(self)
text2 = wx.TextCtrl(panel, size = (300,200), style = wx.NO_BORDER | wx.TE_MULTILINE)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(text2, 1, flag = wx.EXPAND)
panel.SetSizerAndFit(box)
self.mgr.Update()
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Centre()
self.Show(True)
def OnClose(self, event):
self.mgr.UnInit()
self.Destroy()
app = wx.App()
Mywin(None,"Dock Demo")
app.MainLoop()
上面的代码产生以下输出 -
wxPython - Multiple Document Interface
典型的GUI应用程序可以具有多个窗口。 选项卡式和堆叠式小部件允许一次激活一个这样的窗口。 但是,很多时候这种方法可能没有用,因为隐藏了其他窗口的视图。
同时显示多个窗口的一种方法是将它们创建为独立窗口。 这称为SDI( Single Document Interface )。 这需要更多的内存资源,因为每个窗口可能有自己的菜单系统,工具栏等。
wxPython中的MDI框架提供了一个wx.MDIParentFrame类。 它的对象充当多个子窗口的容器,每个子窗口都是wx.MDIChildFrame类的对象。
子窗口驻留在父框架的MDIClientWindow区域中。 添加子框架后,父框架的菜单栏会显示一个窗口菜单,其中包含用于以级联或平铺方式排列子项的按钮。
例子 (Example)
以下示例说明了MDIParentFrame作为顶级窗口的用法。 名为NewWindow的菜单按钮在客户区域中添加子窗口。 可以添加多个窗口,然后以级联或平铺顺序排列。
完整的代码如下 -
import wx
class MDIFrame(wx.MDIParentFrame):
def __init__(self):
wx.MDIParentFrame.__init__(self, None, -1, "MDI Parent", size = (600,400))
menu = wx.Menu()
menu.Append(5000, "&New Window")
menu.Append(5001, "&Exit")
menubar = wx.MenuBar()
menubar.Append(menu, "&File")
self.SetMenuBar(menubar)
self.Bind(wx.EVT_MENU, self.OnNewWindow, id = 5000)
self.Bind(wx.EVT_MENU, self.OnExit, id = 5001)
def OnExit(self, evt):
self.Close(True)
def OnNewWindow(self, evt):
win = wx.MDIChildFrame(self, -1, "Child Window")
win.Show(True)
app = wx.App()
frame = MDIFrame()
frame.Show()
app.MainLoop()
上面的代码产生以下输出 -
wxPython - Drawing API
GDI +(图形绘制界面), CoreGraphics和Cairo libraries构成了wxPython中绘制API的框架。 wx.GraphicsContext是主要的可绘制对象,使用它可以创建各种Device Context对象。
wx.DC是一个抽象类。 其派生类用于在不同设备上呈现图形和文本。 设备上下文类是 -
wx.ScreenDC - 使用它在屏幕上绘画,而不是单个窗口。
wx.ClientDC - 使用它在窗口的客户区域(没有边框和其他装饰的部分)上绘制,但不要在wxPaintEvent中使用它。
wx.PaintDC - 使用它在窗口的客户区域上绘制,但only在wxPaintEvent中绘制。
wx.WindowDC - 用它来绘制窗口的整个区域,包括装饰。 这可能不适用于非Windows平台。
wxPython的绘图API为绘制形状,文本和图像提供了不同的功能。 绘图目的所需的对象,如Color,Pen,Brush和Font也可以使用GDI类构造。
wx.Colour Class
颜色对象表示RGB(红色,绿色和蓝色)强度值的组合,每个强度值的范围为0-255。 有一些预定义的颜色对象,如 -
- wxBLACK
- wxBLUE
- wxCYAN
- wxGREEN
- wxYELLOW
- wxLIGHT_GREY
- wxRED
- wxWHITE
具有RGB值的自定义组合的颜色形成为wx.Colour object 。
wx.Colour(r,g,b)
wx.Pen Class
笔对象确定图形形状的颜色,宽度和样式,如线,矩形,圆等。
Predefined Pen objects是 -
wxBLACK_DASHED_PEN |
wxBLACK_PEN |
wxBLUE_PEN |
wxCYAN_PEN |
wxGREEN_PEN |
wxYELLOW_PEN |
wxGREY_PEN |
wxLIGHT_GREY_PEN |
wxMEDIUM_GREY_PEN |
wxRED_PEN |
wxTRANSPARENT_PEN |
wxWHITE_PEN |
Predefined Pen styles是 -
wx.SOLID |
wx.DOT |
wx.LONG_DASH |
wx.SHORT_DASH |
wx.DOT_DASH |
wx.TRANSPARENT |
wx.Brush Class
画笔是填充形状背景所需的另一个基本图形对象,如矩形,椭圆,圆等。
自定义Brush对象需要wx.Colour和Brush样式参数。 以下是预定义画笔样式的列表 -
wx.SOLID |
wx.STIPPLE |
wx.BDIAGONAL_HATCH |
wx.CROSSDIAG_HATCH |
wx.FDIAGONAL_HATCH |
wx.CROSS_HATCH |
wx.HORIZONTAL_HATCH |
wx.VERTICAL_HATCH |
wx.TRANSPARENT |
wxPython有许多功能,可以方便地绘制不同的形状,文本和图像。
SN | 功能和描述 |
---|---|
1 | DrawRectangle() 绘制给定尺寸的矩形 |
2 | DrawCircle() 在给定点绘制一个圆作为中心和半径 |
3 | DrawEllipse() 绘制具有给定x和y半径的椭圆 |
4 | DrawLine() 在两个wx.Point对象之间绘制一条线 |
5 | DrawBitmap() 在给定位置绘制图像 |
6 | DrawText() 在指定位置显示给定文本 |
例子 (Example)
以下示例在以下示例中实现,使用了Pen,Brush,Color和Font对象。
完整的代码如下 -
import wx
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title,size = (500,300))
self.InitUI()
def InitUI(self):
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Centre()
self.Show(True)
def OnPaint(self, e):
dc = wx.PaintDC(self)
brush = wx.Brush("white")
dc.SetBackground(brush)
dc.Clear()
dc.DrawBitmap(wx.Bitmap("python.jpg"),10,10,True)
color = wx.Colour(255,0,0)
b = wx.Brush(color)
dc.SetBrush(b)
dc.DrawCircle(300,125,50)
dc.SetBrush(wx.Brush(wx.Colour(255,255,255)))
dc.DrawCircle(300,125,30)
font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL)
dc.SetFont(font)
dc.DrawText("Hello wxPython",200,10)
pen = wx.Pen(wx.Colour(0,0,255))
dc.SetPen(pen)
dc.DrawLine(200,50,350,50)
dc.SetBrush(wx.Brush(wx.Colour(0,255,0), wx.CROSS_HATCH))
dc.DrawRectangle(380, 15, 90, 60)
ex = wx.App()
Mywin(None,'Drawing demo')
ex.MainLoop()
上面的代码产生以下输出 -
wxPython - Drag & Drop
为用户提供drag and drop非常直观。 在许多桌面应用程序中都可以找到,用户只需用鼠标拖动对象并放在另一个窗口上就可以将对象从一个窗口复制或移动到另一个窗口。
拖放操作涉及以下步骤 -
- Declare a drop target
- 创建数据对象
- 创建wx.DropSource
- 执行拖动操作
- Cancel or accept drop
在wxPython中,有两个预定义的放置目标 -
- wx.TextDropTarget
- wx.FileDropTarget
许多wxPython小部件支持拖放活动。 源控件必须启用拖动,而目标控件必须处于接受(或拒绝)拖动的位置。
用户拖动的源数据放置在目标对象上。 目标对象的OnDropText()使用数据。 如果需要,可以删除源对象中的数据。
例子 (Example)
在以下示例中,两个ListCrl对象水平放置在Box Sizer中。 左侧的列表中填充了languages []数据。 它被指定为阻力源。 右边一个是目标。
languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript', 'PHP', 'VB.NET','C#']
self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST)
self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST)
for lang in languages:
self.lst1.InsertStringItem(0,lang)
第二个列表控件为空,是TextDropTarget类的对象的参数。
class MyTextDropTarget(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
def OnDropText(self, x, y, data):
self.object.InsertStringItem(0, data)
OnDropText()方法在目标列表控件中添加源数据。
拖动操作由事件绑定器初始化。
wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
OnDragInit()函数将拖动数据放在目标上并从源中删除。
def OnDragInit(self, event):
text = self.lst1.GetItemText(event.GetIndex())
tobj = wx.PyTextDataObject(text)
src = wx.DropSource(self.lst1)
src.SetData(tobj)
src.DoDragDrop(True)
self.lst1.DeleteItem(event.GetIndex())
完整的代码如下 -
import wx
class MyTarget(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
def OnDropText(self, x, y, data):
self.object.InsertStringItem(0, data)
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title,size = (-1,300))
panel = wx.Panel(self)
box = wx.BoxSizer(wx.HORIZONTAL)
languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript',
'PHP', 'VB.NET','C#']
self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST)
self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST)
for lang in languages:
self.lst1.InsertStringItem(0,lang)
dt = MyTarget(self.lst2)
self.lst2.SetDropTarget(dt)
wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
box.Add(self.lst1,0,wx.EXPAND)
box.Add(self.lst2, 1, wx.EXPAND)
panel.SetSizer(box)
panel.Fit()
self.Centre()
self.Show(True)
def OnDragInit(self, event):
text = self.lst1.GetItemText(event.GetIndex())
tobj = wx.PyTextDataObject(text)
src = wx.DropSource(self.lst1)
src.SetData(tobj)
src.DoDragDrop(True)
self.lst1.DeleteItem(event.GetIndex())
ex = wx.App()
Mywin(None,'Drag&Drop Demo')
ex.MainLoop()
上面的代码产生以下输出 -