wxPython学习(7.高级窗口) 您所在的位置:网站首页 wxpython开源协议 wxPython学习(7.高级窗口)

wxPython学习(7.高级窗口)

2024-07-05 17:38| 来源: 网络整理| 查看: 265

1.分隔窗口

分隔窗口就是将窗口分成两部分,即左右或上下两部分。 例:将整体分为左右两个窗口,右窗口又分为上下两窗口,两窗口之间的分隔线是可以拖动的,称为“窗框”

wx.SplitterWindow 中常用的方法有: (1)SplitVertically(window1, window2, sashPosition=0)。 设置左右布局的分隔窗口,window1 为左窗口,window2 为右窗口,sashPosition 是窗框的位置。 (2)SplitHorizontally(window1, window2, sashPosition=0)。 设置上下布局的分隔窗口,window1 为上窗口,window2 为下窗口,sashPosition 是窗框的位置。 (3)SetMinimumPaneSize(paneSize)。 设置最小窗口尺寸,如果是左右布局是指左窗口的最小尺寸,如果是上下布局是指上窗口的最小尺寸。如果没有设置则默认为 0。

分割窗是一种特殊的容器窗口部件,它管理两个子窗口。这两个子窗口可以被水平的堆放或彼此左右相邻。在两个子窗口之间的是一个窗框,它是一个可移动的边框,移动它就改变了两个子窗口的尺寸。分割窗经常被用于主窗口的侧边栏。

1.创建一个分割窗 在wxPython中,分割窗是类wx.SplitterWindow的实例。和大多数其它的wxPython窗口部件不一样,分隔窗口在被创建后,可使用前要求进一步的初始化。

构造函数: wx.SplitterWindow(parent, id=-1, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.SP_3D,name=”splitterWindow”) 它的这些参数都有标准的含义——parent是窗口部件的容器,pos是窗口部件在它的父容器中位置,size是它的尺寸。

2.在创建了这个分割窗后,在它可以被使用前,你必须对这个窗口调用三个方法中的一处。如果你想初始时只显示一个子窗口,那么调用Initialize(window),参数window是这个单一的子窗口(通常是一种wx.Panel)。在这种情况下,窗口将在以后响应用户的动作时再分割。

3.要显示两个子窗口,使用SplitHorizontally (window1,window2,sashPosition=0)或SplitVertically(window1, window2, sashPosition=0)。 两个方法的工作都是相似的,参数window1和window2包含两个子窗口,参数sashPosition包含分割条的初始位置。对于水平分割(水平分割条)来说,window1被放置在window2的顶部。如果sashPosition是一个正数,它代表顶部窗口的初始高度(也就是分割条距顶部的像素值)。如果sashPosition是一个负数,它定义了底部窗口的尺寸,或分割条距底部的像素值。如果sashPosition是0,那么这个分割条位于正中。对于垂直分割(垂直分割条),window1位于左边,window2位于右边。 正值的sashPosition设置window1的尺寸,也就是分割条距左边框的像素值。类似的,负值sashPosition设置右边子窗口的尺寸,0值将分割条放置在正中。如果你的子窗口复杂的话,我们建议你在布局中使用sizer,以便于当分割条被移动时很好地调整窗口的大小。

例:如图

#分隔窗口 import wx # 自定义窗口类MyFrame class MyFrame(wx.Frame): def __init__(self): super().__init__(parent=None, title='分隔窗口', size=(350, 180)) self.Centre() # 设置窗口居中 #创建一个分隔窗 splitter = wx.SplitterWindow(self, -1) #创建子面板 leftpanel = wx.Panel(splitter) rightpanel = wx.Panel(splitter) #分隔窗口 splitter.SplitVertically(leftpanel, rightpanel, 100) splitter.SetMinimumPaneSize(80)#设置最小窗口尺寸,这里指的是左窗口尺寸 #列表,单选 list2 = ['苹果', '橘子', '香蕉'] lb2 = wx.ListBox(leftpanel, -1, choices=list2, style=wx.LB_SINGLE) self.Bind(wx.EVT_LISTBOX, self.on_listbox, lb2)#绑定事件 #创建一个垂直方向的box布局管理器vbox1,将列表添加到vbox中,将vbox1添加到左侧控制面板中 vbox1 = wx.BoxSizer(wx.VERTICAL) vbox1.Add(lb2, 1, flag=wx.ALL | wx.EXPAND, border=5) leftpanel.SetSizer(vbox1) #创建一个垂直方向的box布局管理器vbox2,创建一个静态文本并添加到vbox2中,将vbox2添加到右侧面板中 vbox2 = wx.BoxSizer(wx.VERTICAL) self.content = wx.StaticText(rightpanel, label='右侧面板') vbox2.Add(self.content, 1, flag=wx.ALL | wx.EXPAND, border=5) rightpanel.SetSizer(vbox2) def on_listbox(self, event): s = '选择 {0}'.format(event.GetString()) self.content.SetLabel(s) class App(wx.App): def OnInit(self): # 创建窗口对象 frame = MyFrame() frame.Show() return True if __name__ == '__main__': app = App() app.MainLoop() # 进入主事件循环

 

2.使用树

树(tree)是一种通过层次结构展示信息的控件,在wxPython中树控件类是wx.TreeCtrl

wx.TreeCtrl 中常用的方法有: (1)AddRoot(text, image=-1, selImage=-1, data=None)。 添加根节点,text 参数根节点显示的文本;image 参数是该节点未被选中时的图片索引,wx.TreeCtrl 中使用的图片被放到 wx.ImageList 图像列表中;selImage 参数是该节点被选中时的图片索引。data 参数是给节点传递的数据。方法返回节点,节点类型是 wx.TreeItemId。 (2)AppendItem(parent, text, image=-1, selImage=-1, data=None)。 添加子节点,parent 参数是父节点,其他参数同 AddRoot()方法。方法返回值 wx.TreeItemId。 (3)SelectItem(item, select=True)。选中 item 节点 (4)Expand(item)。展开 item 节点 (5)ExpandAll()。展开根节点下的所有子节点。 (6)ExpandAllChildren(item)。展开 item 节点下的所有子节点。 (7)AssignImageList(imageList)。保存 wx.ImageList 图像列表到树中,这样就可以在AddRoot()和 AppendItem()方法中使用图像列表索引了。

wx.TreeCtrl的构造函数是一个典型的wxPython窗口部件构造函数: wx.TreeControl(parent, id=-1, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS,validator=wx.DefaultValidator, name=”treeCtrl”) 该构造函数提供给你了一个没有元素的空的树。

1.当你将项目添加到树时,你首先必须要添加的项目是root(根)元素。添加根元素的方法如下所示: AddRoot(text, image=-1, selImage=-1, data=None) 你只能添加一个根元素。如果你在已经存在一个根元素后,再添加第二根元素的话,那么wxPython将引发一个异常。其中的参数text包含用于根元素的显示字符串。参数image是图像列表中的一个索引,代表要显示在参数text旁边的图像。它的行为类似于用于列表控件的图像列表。参数data是一个与项目相关的数据对象,主要的目的是分类。

AddRoot()方法返回一个关于根项目的ID。树形控件使用它自己的类wx.TreeItemId来管理项目。在大多数时候,你不需要关心ID的具体值,你只需要知道每个项目都有一个唯一的wx.TreeItemId就够了,并且这个值可以使用等号测试。wx.TreeItemId不映射到任何简单的类型——它的值没有任何的关联性,因为你只是把它用于相等测试。

2.一旦你有了根元素,你就可以开始向树中添加元素了。用的最多的方法是 AppendItem(parent, text, image=-1, selImage=-1, data=None)。 参数parent是已有的树项目的wx.TreeItemId,它作为新项目的父亲。参数text是显示新项目的文本字符串。参数image和selImage的意义与方法AddRoot()中的相同。该方法将新的项目放置到其父项目的孩子列表的末尾。这个方法返回新创建的项目的wx.TreeItemId。如果你想给新的项目添加子项目的话,你需要拥有这个ID。

rootId = tree.AddRoot(“The Root”) childId = tree.AppendItem(rootId, ”A Child”) grandChildId = tree.AppendItem(childId, ”A Grandchild”) 上面的这个代码片断增加了一个root(根)项目,然后给根项目添加了一个子项目,然后给子项目添加了它的子项目。

如果要将子项目添加到孩子列表的开头的话,使用方法PrependItem(parent, text, image=-1, selImage=-1, data=None)。

如果你想将一个项目插入树的任意点上,你可以使用后面的两种方法之一。 第一个是InsertItem(parent, previous, text,image=-1, selImage=-1, data=None)。 其中参数previous其父项目中的子列表中的项目的wx.TreeItemId。插入的项目将放置在该项目的后面。 第二个方法是InsertItemBefore(parent, before, text, image=-1, selImage=-1, data=None)。 该方法将新的项目放置在before所代表的项目之前。然而参数before不是一个项目的ID。它是项目在孩子列表中的整数索引。第二个方法返回新项目的一个wx.TreeItemId。

3.要去掉树中的一个项目,可以使用Delete(item)方法,其中参数item是该项目的wx.TreeItemId。调用这个方法将导致一个EVT_TREE_Delete_ITEM类型的树的事件被触发。后面的章节我们将讨论树的事件类型。要删除一个项目的所有子项目,而留下该项目自身,可以使用方法DeleteChildren(item),其中参数item也是一个wx.TreeItemId。该方法不产生一个删除事件。要清除整个树,使用方法DeleteAllItems()。该方法为每个项目生成一个删除事件,但是,这在某些老版的Windows系统上不工作。

4.一旦你将一个项目添加到树中,你就可以使用方法GetItemText(item)来得到该项目在显示在树中的文本,其中参数item是一个wx.TreeItemId。如果你想改变一个项目的显示文本,可以使用方法SetItemText(item, text),其中参数item是一个wx.TreeItemId,参数text是一个新的显示文本。

5.你可以使用方法GetCount()来得到树中项目的总数。如果你想得到特定项目下的子项目的数量,可以使用方法GetChildrenCount(item, recursively=True)。其中参数item是一个wx.TreeItemId,参数recursively如果为False,那么该方法只返回直接的子项目的数量,如果为True,则返回所有的子项目而不关嵌套有多深。

样式:树控件中的按钮 wx.TR_HAS_BUTTONS:有按钮。在Windows上,+用于标明项目可以被展开,-表示可以折叠。 wx.TR_NO_BUTTONS:没有按钮。

树控件中的连接线:它们决定树控件将连接线绘制在何处。 wx.TR_LINES_AT_ROOT:如果设置了这个样式,那么树控件将在多个root项目之间绘制连线。注意,如果wx.TR_HIDE_ROOT被设置了,那么你就有多个root项目。 wx.TR_NO_LINES:如果设置了这个样式,那么树控件将不在兄弟项目间绘制连接线。这个样式将代替wx.TR_LINES_AT_ROOT。 wx.TR_ROW_LINES :树控件在行之间将绘制边距

树控件的选择模式 wx.TR_EXTENDED:可以选择多个不连续的项。不是对所有的系统有效。 wx.TR_MULTIPLE:可以选择一块且仅一块连续的项。 wx.TR_SINGLE:一次只能选择一个结点。这是默认模式。

树的其它显示样式 wx.TR_FULL_ROW_HIGHLIGHT:如果设置了这个样式,那么当被选择时,被选项的整个行将高亮显示。默认情况下,只是文本区高亮。在Windows上,该样式只在也设置wx.NO_LINES时有效。 wx.TR_HAS_VARIABLE_ROW_HEIGHT:如果设置了这个样式,则行的高度将根据其中的图像和文本而不同。否则,所有的行将是同样的高度(取决于最高的行)。 wx.TR_HIDE_ROOT:如果设置了这个样式,则通过AddRoot()确定的root元素将不被显示。此时该结节的所有子项就如同它们是root一样显示。这个样式用于让一个树具有多个root元素的外观。

当树控件中发生选择变化的时候,有两个事件将被触发并可被捕获。第一个事件是wx.EVT_TREE_SEL_CHANGING,它在被选项实际改变之前发生。如果你要处理这个事件,你可以使用事件的Veto()方法来阻止选择的改变。在选择已经改变之后,事件wx.EVT_TREE_SEL_CHANGED被触发。这两个事件的类是wx.TreeEvent

树控件的另外的几个事件 wx.EVT_TREE_BEGIN_DRAG:当用户通过按下鼠标左键来拖动树中的一个项目时,触发该事件。要让拖动时能够做些事情,该事件的处理函数必须显式地调用事件的Allow()方法。 wx.EVT_TREE_BEGIN_RDRAG:当用户通过按下鼠标右键来拖动树中的一个项目时,触发该事件。要让拖动时能够做些事情,该事件的处理函数必须显式地调用事件的Allow()方法。 wx.EVT_TREE_ITEM_ACTIVATED:当一个项目通过双击被激活时,触发该事件。 wx.EVT_TREE_ITEM_GETTOOLTIP:当鼠标停留在树中的一个项目上时,触发该事件。该事件可用来为项目设置特定的提示。只需要在事件对像中简单地设置标签参数,其它的将由系统来完成。 wx.EVT_TREE_KEY_DOWN:在树控件获得焦点的情况下,当一个键被按下时触发该事件。

例:如图

#使用树 import wx # 自定义窗口类MyFrame class MyFrame(wx.Frame): def __init__(self): super().__init__(parent=None, title='树控件', size=(500, 400)) self.Centre() # 设置窗口居中 splitter = wx.SplitterWindow(self) leftpanel = wx.Panel(splitter) rightpanel = wx.Panel(splitter) splitter.SplitVertically(leftpanel, rightpanel, 200) splitter.SetMinimumPaneSize(80) #创建并初始化一个树 self.tree = self.CreateTreeCtrl(leftpanel)#传递过去父容器 #绑定点击事件 self.Bind(wx.EVT_TREE_SEL_CHANGING, self.on_click, self.tree) vbox1 = wx.BoxSizer(wx.VERTICAL) vbox1.Add(self.tree, 1, flag=wx.ALL | wx.EXPAND, border=5) leftpanel.SetSizer(vbox1) vbox2 = wx.BoxSizer(wx.VERTICAL) self.content = wx.StaticText(rightpanel, label='右侧面板') vbox2.Add(self.content, 1, flag=wx.ALL | wx.EXPAND, border=5) rightpanel.SetSizer(vbox2) def on_click(self, event): item = event.GetItem() self.content.SetLabel(self.tree.GetItemText(item))#选中的节点的文本写入右侧静态文本中 #创建并初始化一个tree def CreateTreeCtrl(self, parent): #创建一个tree tree = wx.TreeCtrl(parent) items = [] #创建图像列表,宽、高、掩模、初始容量 imglist = wx.ImageList(16, 16, True, 2) #参数:图片、尺寸,这里用的自带的图片 imglist.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, size=wx.Size(16, 16))) imglist.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, size=wx.Size(16, 16))) tree.AssignImageList(imglist)#将图片绑定到树上 root = tree.AddRoot("TreeRoot", image=0)#添加根节点 items.append(tree.AppendItem(root, "Item 1", 0))#添加子节点 items.append(tree.AppendItem(root, "Item 2", 0)) items.append(tree.AppendItem(root, "Item 3", 0)) items.append(tree.AppendItem(root, "Item 4", 0)) items.append(tree.AppendItem(root, "Item 5", 0)) #遍历每个子节点,并添加子元素 for ii in range(len(items)): id = items[ii] tree.AppendItem(id, "Subitem 1", 1) tree.AppendItem(id, "Subitem 2", 1) tree.AppendItem(id, "Subitem 3", 1) tree.AppendItem(id, "Subitem 4", 1) tree.AppendItem(id, "Subitem 5", 1) #初始树的状态 tree.Expand(root) # 展开根下子节点 tree.Expand(items[0]) # 展开Item 1下子节点 tree.Expand(items[3]) # 展开Item 4下子节点 tree.SelectItem(root) # 选中根节点 return tree class App(wx.App): def OnInit(self): # 创建窗口对象 frame = MyFrame() frame.Show() return True if __name__ == '__main__': app = App() app.MainLoop() # 进入主事件循环

 

3.使用网格

wxPython 网格类是 wx.grid.Grid。

添加单元格数据比较麻烦,而且对于网格的控制也很少,为此可以使用wx.grid.GridTableBase类,该类是一个抽象类,开发人员需要实现给类的一些方法。

网格鼠标事件的单元格事件类型 wx.grid.EVT_GRID_CELL_CHANGE:当用户通过编辑器改变单元格中的数据时触发该事件。 wx.grid.EVT_GRID_CELL_LEFT_CLICK:当用户在一个单元格中敲击鼠标左键时触发该事件。 wx.grid.EVT_GRID_CELL_LEFT_DCLICK:当用户在一个单元格中双击鼠标左键时触发该事件。 wx.grid.EVT_GRID_CELL_RIGHT_CLICK:当用户在一个单元格中敲击鼠标右键时触发该事件。 wx.grid.EVT_GRID_CELL_RIGHT_DCLICK:当用户在一个单元格中双击鼠标右键时触发该事件。 wx.grid.EVT_GRID_EDITOR_HIDDEN:当在编辑会话结束时隐藏一个单元格编辑器则触发该事件。 wx.grid.EVT_GRID_EDITOR_SHOWN:当在编辑会话结束时显示一个单元格编辑器则触发该事件。 wx.grid.EVT_GRID_LABEL_LEFT_CLICK:当用户在行或列的标签区域敲击鼠标左键时触发该事件。 wx.grid.EVT_GRID_LABEL_LEFT_DCLICK:当用户在行或列的标签区域双击鼠标左键时触发该事件。 wx.grid.EVT_GRID_LABEL_RIGHT_CLICK:当用户在行或列的标签区域敲击鼠标右键时触发该事件。 wx.grid.EVT_GRID_LABEL_RIGHT_DCLICK:当用户在行或列的标签区域双击鼠标右键时触发该事件。 wx.grid.EVT_GRID_Select_CELL:当用户将焦点移到一个新的单元格,并选择它时触发该事件。

要将网格表实例附着于你的表的实例,要调用SetTable(table,takeOwnership=False,selmode=wx.grid.Grid.SelectCells)方法。其中参数table是你的wx.grid.PyGridTableBase的实例。参数takeOwnership使得网格控件拥有这个表。如果takeOwnership为True,那么当网格被删除时,该表也被wxPython系统删除。参数selmode作用等同于在CreateGrid()中的作用。

例:如图

#使用网格 import wx import wx.grid #list of list data = [['0036', '高等数学', '李放', '人民邮电出版社', '20000812', '1'], ['0004', 'FLASH精选', '刘扬', '中国纺织出版社', '19990312', '2'], ['0026', '软件工程', '牛田', '经济科学出版社', '20000328', '4'], ['0015', '人工智能', '周未', '机械工业出版社', '19991223', '3'], ['0037', '南方周末', '邓光明', '南方出版社', '20000923', '3'], ['0008', '新概念3', '余智', '外语出版社', '19990723', '2'], ['0019', '通讯与网络', '欧阳杰', '机械工业出版社', '20000517', '1'], ['0014', '期货分析', '孙宝', '飞鸟出版社', '19991122', '3'], ['0023', '经济概论', '思佳', '北京大学出版社', '20000819', '3'], ['0017', '计算机理论基础', '戴家', '机械工业出版社', '20000218', '4'], ['0002', '汇编语言', '李利光', '北京大学出版社', '19980318', '2'], ['0033', '模拟电路', '邓英才', '电子工业出版社', '20000527', '2'], ['0011', '南方旅游', '王爱国', '南方出版社', '19990930', '2'], ['0039', '黑幕', '李仪', '华光出版社', '20000508', '14'], ['0001', '软件工程', '戴国强', '机械工业出版社', '19980528', '2'], ['0034', '集邮爱好者', '李云', '人民邮电出版社', '20000630', '1'], ['0031', '软件工程', '戴志名', '电子工业出版社', '20000324', '3'], ['0030', '数据库及应用', '孙家萧', '清华大学出版社', '20000619', '1'], ['0024', '经济与科学', '毛波', '经济科学出版社', '20000923', '2'], ['0009', '军事要闻', '张强', '解放军出版社', '19990722', '3'], ['0003', '计算机基础', '王飞', '经济科学出版社', '19980218', '1'], ['0020', '现代操作系统', '王小国', '机械工业出版社', '20010128', '1'], ['0025', '计算机体系结构', '方丹', '机械工业出版社', '20000328', '4'], ['0010', '大众生活', '许阳', '电子出版社', '19990819', '3'], ['0021', '网络基础', '王大尉', '北京大学出版社', '20000617', '1'], ['0006', '世界杯', '柳飞', '世界出版社', '19990412', '2'], ['0028', '高级语言程序设计', '寇国华', '清华大学出版社', '20000117', '3'], ['0038', '十大旅游胜地', '潭晓明', '南方出版社', '20000403', '2'], ['0018', '编译原理', '郑键', '机械工业出版社', '20000415', '2'], ['0007', 'JAVA程序设计', '张余', '人民邮电出版社', '19990613', '1'], ['0013', '幽灵', '钱力华', '华光出版社', '19991008', '1'], ['0022', '万紫千红', '丛丽', '北京大学出版社', '20000702', '3'], ['0027', '世界语言大观', '候丙辉', '经济科学出版社', '20000814', '2'], ['0029', '操作系统概论', '聂元名', '清华大学出版社', '20001028', '1'], ['0016', '数据库系统概念', '吴红', '机械工业出版社', '20000328', '3'], ['0005', 'java基础', '王一', '电子工业出版社', '19990528', '3'], ['0032', 'SQL使用手册', '贺民', '电子工业出版社', '19990425', '2']] column_names = ['书籍编号', '书籍名称', '作者', '出版社', '出版日期', '库存数量'] # 自定义窗口类MyFrame class MyFrame(wx.Frame): def __init__(self): super().__init__(parent=None, title='网格控件', size=(550, 500)) self.Centre() # 设置窗口居中 #创建成员变量,一个网格对象 self.grid = self.CreateGrid(self) #绑定事件,当用户在行或列的标签区域敲击鼠标左键时触发该事件 self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.OnLabelLeftClick) def OnLabelLeftClick(self, event): print("RowIdx:{0}".format(event.GetRow()))#行索引 print("ColIdx:{0}".format(event.GetCol()))#列索引 print(data[event.GetRow()]) event.Skip()#确保还可以响应其他事件处理 #创建网格对象 def CreateGrid(self, parent): grid = wx.grid.Grid(parent) grid.CreateGrid(len(data), len(data[0]))#行、列 #添加数据 for row in range(len(data)): for col in range(len(data[row])): grid.SetColLabelValue(col, column_names[col])#设置列标题 grid.SetCellValue(row, col, data[row][col])#设置单元格内容 #SetRowLabelValue(),SetColLabelValue()和SetCellValue(),它们实际上设置显示在网格中的值 #SetCellValue()方法要求一个行索引、一个列索引和一个值。而其它两个方法要求一个索引和一个值。 # 设置行和列自定调整 grid.AutoSize() return grid class App(wx.App): def OnInit(self): # 创建窗口对象 frame = MyFrame() frame.Show() return True if __name__ == '__main__': app = App() app.MainLoop() # 进入主事件循环

另一种方法,使用自定义网格

import wx import wx.grid data = [['0036', '高等数学', '李放', '人民邮电出版社', '20000812', '1'], ['0004', 'FLASH精选', '刘扬', '中国纺织出版社', '19990312', '2'], ['0026', '软件工程', '牛田', '经济科学出版社', '20000328', '4'], ['0015', '人工智能', '周未', '机械工业出版社', '19991223', '3'], ['0037', '南方周末', '邓光明', '南方出版社', '20000923', '3'], ['0008', '新概念3', '余智', '外语出版社', '19990723', '2'], ['0019', '通讯与网络', '欧阳杰', '机械工业出版社', '20000517', '1'], ['0014', '期货分析', '孙宝', '飞鸟出版社', '19991122', '3'], ['0023', '经济概论', '思佳', '北京大学出版社', '20000819', '3'], ['0017', '计算机理论基础', '戴家', '机械工业出版社', '20000218', '4'], ['0002', '汇编语言', '李利光', '北京大学出版社', '19980318', '2'], ['0033', '模拟电路', '邓英才', '电子工业出版社', '20000527', '2'], ['0011', '南方旅游', '王爱国', '南方出版社', '19990930', '2'], ['0039', '黑幕', '李仪', '华光出版社', '20000508', '14'], ['0001', '软件工程', '戴国强', '机械工业出版社', '19980528', '2'], ['0034', '集邮爱好者', '李云', '人民邮电出版社', '20000630', '1'], ['0031', '软件工程', '戴志名', '电子工业出版社', '20000324', '3'], ['0030', '数据库及应用', '孙家萧', '清华大学出版社', '20000619', '1'], ['0024', '经济与科学', '毛波', '经济科学出版社', '20000923', '2'], ['0009', '军事要闻', '张强', '解放军出版社', '19990722', '3'], ['0003', '计算机基础', '王飞', '经济科学出版社', '19980218', '1'], ['0020', '现代操作系统', '王小国', '机械工业出版社', '20010128', '1'], ['0025', '计算机体系结构', '方丹', '机械工业出版社', '20000328', '4'], ['0010', '大众生活', '许阳', '电子出版社', '19990819', '3'], ['0021', '网络基础', '王大尉', '北京大学出版社', '20000617', '1'], ['0006', '世界杯', '柳飞', '世界出版社', '19990412', '2'], ['0028', '高级语言程序设计', '寇国华', '清华大学出版社', '20000117', '3'], ['0038', '十大旅游胜地', '潭晓明', '南方出版社', '20000403', '2'], ['0018', '编译原理', '郑键', '机械工业出版社', '20000415', '2'], ['0007', 'JAVA程序设计', '张余', '人民邮电出版社', '19990613', '1'], ['0013', '幽灵', '钱力华', '华光出版社', '19991008', '1'], ['0022', '万紫千红', '丛丽', '北京大学出版社', '20000702', '3'], ['0027', '世界语言大观', '候丙辉', '经济科学出版社', '20000814', '2'], ['0029', '操作系统概论', '聂元名', '清华大学出版社', '20001028', '1'], ['0016', '数据库系统概念', '吴红', '机械工业出版社', '20000328', '3'], ['0005', 'java基础', '王一', '电子工业出版社', '19990528', '3'], ['0032', 'SQL使用手册', '贺民', '电子工业出版社', '19990425', '2']] column_names = ['书籍编号', '书籍名称书籍名称', '作者', '出版社', '出版日期', '库存数量'] #自定义网格 class MyGridTable(wx.grid.GridTableBase): #构造方法 def __init__(self): super().__init__() self.colLabels = column_names#成员变量,列标题 #要求类实现的方法,因为wx.grid.GridTableBase类,该类是一个抽象类 def GetNumberRows(self): #获取行数 return len(data) def GetNumberCols(self): # 获取列数 return len(data[0]) def GetValue(self, row, col): # 获取每个单元格值 return data[row][col] def GetColLabelValue(self, col): # 获取一列的标签 return self.colLabels[col] # 自定义窗口类MyFrame class MyFrame(wx.Frame): def __init__(self): super().__init__(parent=None, title='网格控件', size=(550, 500)) self.Centre() # 设置窗口居中 self.grid = self.CreateGrid(self) self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.OnLabelLeftClick) def OnLabelLeftClick(self, event): print("RowIdx:{0}".format(event.GetRow())) print("ColIdx:{0}".format(event.GetCol())) print(data[event.GetRow()]) event.Skip() def CreateGrid(self, parent): grid = wx.grid.Grid(parent) tablebase = MyGridTable() grid.SetTable(tablebase, True)#把自定义的MyGridTable放进去实例化 # 设置行和列自定调整 grid.AutoSize() return grid class App(wx.App): def OnInit(self): # 创建窗口对象 frame = MyFrame() frame.Show() return True if __name__ == '__main__': app = App() app.MainLoop() # 进入主事件循环

 

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有