效果视频
我们将这样的子窗口称之为‘悬停窗口’ 或 ‘停靠窗口’, 亦或是 ‘浮动窗口’
因为他们可以停靠在Frame某个边,也可悬停在任意地方,并可拖着浮游移动
下文统称为 ‘停靠框’
wxAuiManage介绍
wxAuiManage是wxWidgets中用来管理wxFrame相关联的子窗口(wxPanel)的,它可以通过设置相关属性让子窗口停靠在上、下、左、右、中等位置与标题
参数介绍
import wx.aui
mg = wx.aui.AuiManager(parent)
mg.AddPane(window, direction, caption) 第一种
mg.AddPane(window, pane_info) 第二种
使用上面代码可以让子窗口wxPanel停靠在其wxFrame下
**wx.aui.AuiManager()**是创建aui管理对象,里的参数是wxFreame对象
**AddPane()**方法是将wxPanel对象加入管理起来,通过传参决定停靠位置与窗口标题
addPane方法参数(第一种)
参数 | 涵义 |
---|---|
window | wxFrame子窗口wxPanel的对象 |
direction | 停靠位置 ,wx.LEFT、wx.RIGHT、 wx.TOP、wx.DOWN、wx,CENTER |
caption | 标题,停靠框标题展示的文字 |
addPane方法参数(第二种)
参数 | 涵义 |
---|---|
window | wxFrame子窗口wxPanel的对象 |
pane_info | wx.aui.AuiPaneInfo()的对象的方法 |
举例:
mg.AddPane(window=pa1, pane_info=wx.aui.AuiPaneInfo().Bottom().Caption("MyPanel1"))
Buttom()表示停靠在底部与wx.DOWN性能一样,.Caption(‘MyPanel1’)表示停靠框标题展示的文字展示的文字为MyPanel1
wx.aui.AuitPaneInfo()设置停靠窗的属于方法是连起来用的
xxx.Bottom().Caption(“MyPanel1”)
wxAuiManage实战
1、用工具生成基础代码
偷懒使用wxFormBuilder工具设计页面,生成wxFame与wxPanel的基础代码
生成代码如下:
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Jun 17 2015)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
###########################################################################
## Class MyFrame1
###########################################################################
class MyFrame1 ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
self.m_menubar1 = wx.MenuBar( 0 )
self.m_menu1 = wx.Menu()
self.m_menuItem1 = wx.MenuItem( self.m_menu1, wx.ID_ANY, u"左 框", wx.EmptyString, wx.ITEM_NORMAL )
self.m_menu1.Append( self.m_menuItem1 )
self.m_menuItem2 = wx.MenuItem( self.m_menu1, wx.ID_ANY, u"右 框", wx.EmptyString, wx.ITEM_NORMAL )
self.m_menu1.Append( self.m_menuItem2 )
self.m_menuItem3 = wx.MenuItem( self.m_menu1, wx.ID_ANY, u"下 框", wx.EmptyString, wx.ITEM_NORMAL )
self.m_menu1.Append( self.m_menuItem3 )
self.m_menubar1.Append( self.m_menu1, u"工 具" )
self.SetMenuBar( self.m_menubar1 )
self.Centre( wx.BOTH )
# Connect Events
self.Bind( wx.EVT_MENU, self.on_left, id = self.m_menuItem1.GetId() )
self.Bind( wx.EVT_MENU, self.on_right, id = self.m_menuItem2.GetId() )
self.Bind( wx.EVT_MENU, self.on_buttom, id = self.m_menuItem3.GetId() )
def __del__( self ):
pass
# Virtual event handlers, overide them in your derived class
def on_left( self, event ):
event.Skip()
def on_right( self, event ):
event.Skip()
def on_buttom( self, event ):
event.Skip()
###########################################################################
## Class MyPanel1
###########################################################################
class MyPanel1 ( wx.Panel ):
def __init__( self, parent ):
wx.Panel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 158,137 ), style = wx.TAB_TRAVERSAL )
bSizer2 = wx.BoxSizer( wx.VERTICAL )
self.m_staticText2 = wx.StaticText( self, wx.ID_ANY, u"左框", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText2.Wrap( -1 )
bSizer2.Add( self.m_staticText2, 0, wx.ALL, 5 )
self.SetSizer( bSizer2 )
self.Layout()
def __del__( self ):
pass
###########################################################################
## Class MyPanel2
###########################################################################
class MyPanel2 ( wx.Panel ):
def __init__( self, parent ):
wx.Panel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 173,154 ), style = wx.TAB_TRAVERSAL )
bSizer3 = wx.BoxSizer( wx.VERTICAL )
self.m_staticText3 = wx.StaticText( self, wx.ID_ANY, u"右框", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText3.Wrap( -1 )
bSizer3.Add( self.m_staticText3, 0, wx.ALL, 5 )
self.SetSizer( bSizer3 )
self.Layout()
def __del__( self ):
pass
###########################################################################
## Class MyPanel3
###########################################################################
class MyPanel3 ( wx.Panel ):
def __init__( self, parent ):
wx.Panel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.TAB_TRAVERSAL )
bSizer5 = wx.BoxSizer( wx.VERTICAL )
self.m_staticText5 = wx.StaticText( self, wx.ID_ANY, u"主框", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText5.Wrap( -1 )
bSizer5.Add( self.m_staticText5, 0, wx.ALL, 5 )
self.SetSizer( bSizer5 )
self.Layout()
def __del__( self ):
pass
###########################################################################
## Class MyPanel4
###########################################################################
class MyPanel4 ( wx.Panel ):
def __init__( self, parent ):
wx.Panel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.TAB_TRAVERSAL )
bSizer6 = wx.BoxSizer( wx.VERTICAL )
self.m_staticText6 = wx.StaticText( self, wx.ID_ANY, u"下框", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText6.Wrap( -1 )
bSizer6.Add( self.m_staticText6, 0, wx.ALL, 5 )
self.SetSizer( bSizer6 )
self.Layout()
def __del__( self ):
pass
2、实现停靠框(核心代码)
将基础代码生成后
我们打开pycharme,打开常写demo的目录,没有的话,随便 open一个目录
在目录下建一个目录,随便取名都可以,我这里取了wxAuiMange
将生成 的基础代码noname.py放在目录下
新增一个main.py目录
在main.py编写代码
"""""""""""""""""""""""""""""""""""""""""""""""""""
#@className : main.py
#@author : HunWei
#@descript : 实现悬停框体
#@Time : 2022/11/15 11:01
#@File : main.py
"""""""""""""""""""""""""""""""""""""""""""""""""""
import wx
from noname import MyPanel1, MyPanel2, MyFrame1, MyPanel3, MyPanel4
import wx.aui
'''
继承基础代码里的wxPanel类
'''
class P1(MyPanel1):
def __init__(self, parent):
super(P1, self).__init__(parent)
class P2(MyPanel2):
def __init__(self, parent):
super(P2, self).__init__(parent)
class P3(MyPanel3):
def __init__(self, parent):
super(P3, self).__init__(parent)
class P4(MyPanel4):
def __init__(self, parent):
super(P4, self).__init__(parent)
'''
继承基础代码里的wxFrame类
'''
class MF(MyFrame1):
def __init__(self, parent):
super(MF, self).__init__(parent)
self.aui_Manage()
self.Bind(wx.EVT_CLOSE, self.OnClose)
#控制三个停靠窗口展示与否的标识flag
self.p1flag = 0
self.p2flag = 0
self.p4flag = 0
def aui_Manage(self):
'''
初始化wxPanel四个子窗口,一个中间主框,另三个分别是左,右,下框
初始化wx.aui.AuiManage对象
:return:
'''
p3 = P3(self)
p3.Show(False)
self.p1 = P1(self)
self.p1.Show(False) #这里需要先隐藏,想知道为什么,可注释掉这个看看效果
self.p2 = P2(self)
self.p2.Show(False)
self.p4 = P4(self)
self.p4.Show(False)
self.am = wx.aui.AuiManager(self)
self.am.AddPane(p3, direction=wx.CENTER, caption='中间主框') #先将中间主框稳定好
self.am.Update()
def OnClose(self, event):
self.am.UnInit()
self.Destroy()
# Virtual event handlers, overide them in your derived class
def on_left(self, event):
'''
菜单:工具-左边 的响应函数,实现左边框的停靠展示与隐藏
:param event:
:return:
'''
if self.p1flag == 0:
self.am.AddPane(self.p1, direction=wx.LEFT, caption='左框')
self.p1flag = 1
else:
self.p1flag = 0
self.am.DetachPane(self.p1)
self.p1.Show(False)
self.am.Update()
event.Skip()
def on_right(self, event):
'''
菜单:工具-右边 的响应函数,实现右边框的停靠展示与隐藏
:param event:
:return:
'''
if self.p2flag == 0:
self.am.AddPane(self.p2, direction=wx.RIGHT, caption='右框')
self.p2flag = 1
else:
self.am.DetachPane(self.p2)
self.p2.Show(False)
self.p2flag = 0
self.am.Update()
event.Skip()
def on_buttom(self, event):
'''
菜单:工具-下边 的响应函数,实现右边框的停靠展示与隐藏
:param event:
:return:
'''
if self.p4flag == 0:
self.am.AddPane(self.p4, wx.aui.AuiPaneInfo().Bottom().Caption("下边框,每二种")) # 这里使用第二种参数方法
self.p4flag = 1
else:
self.am.DetachPane(self.p4)
self.p4.Show(False)
self.p4flag = 0
self.am.Update()
event.Skip()
if __name__=='__main__':
app = wx.App()
win = MF(None)
win.Show()
app.MainLoop()
运行代码,展示如下,停靠窗口展示,需要点击‘工具’下的子菜单
比如点击 ‘ 工具 --左边‘
左边停靠窗展示出来了,其他窗口也一样
我们见过很多客户端工具都是使用停靠框来管理子窗口的,一起来学习吧
好了,本文至此结束,希望一键三连:点赞,收藏,关注