2017-09-13 75 views
0

这是我迄今创建的表。使用python的wx.grid,你如何合并列?

enter image description here

这是我想它的样子,与列合并。

enter image description here

我想在每个三列合并列昨天和今天。所以昨天会高于股票,波动和现金。然后同样适用于今天。我找到了一个叫做wx.grid.SetColSize(self, int col, int width)的函数,但它没有任何作用。有谁知道如何做到这一点?

这是我的代码。

import wx 
import wx.grid as gridlib 

class MyForm(wx.Frame): 
    def __init__(self): 
     """Constructor""" 
     wx.Frame.__init__(self, parent=None, title="Strategies' Allocations") 
     self.panel = wx.Panel(self) 

     button_refresh = wx.Button(self.panel, id=wx.ID_ANY, label='Refresh') 
     button_refresh.Bind(wx.EVT_BUTTON, self.refresh) 

     self.myGrid1 = gridlib.Grid(self.panel) 
     self.myGrid1.CreateGrid(2, 6) 

     self.myGrid1.SetRowLabelSize(60) 
     self.myGrid1.SetRowLabelValue(0, "") 
     self.myGrid1.SetRowLabelValue(1, "ABRVXX") 

     for i in range(6): 
      self.myGrid1.SetColSize(i, 60) 

     self.myGrid1.SetColLabelValue(0, "") 
     self.myGrid1.SetColLabelValue(1, "Yesterday") 
     self.myGrid1.SetColLabelValue(2, "") 
     self.myGrid1.SetColLabelValue(3, "") 
     self.myGrid1.SetColLabelValue(4, "Today") 
     self.myGrid1.SetColLabelValue(5, "") 

     self.myGrid1.SetCellValue(0, 0, "Equity") 
     self.myGrid1.SetCellValue(0, 1, "Volatility") 
     self.myGrid1.SetCellValue(0, 2, "Cash") 
     self.myGrid1.SetCellValue(0, 3, "Equity") 
     self.myGrid1.SetCellValue(0, 4, "Volatility") 
     self.myGrid1.SetCellValue(0, 5, "Cash") 

     self.myGrid1.SetColLabelAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) 
     self.myGrid1.SetDefaultCellAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP) 
     # ******************************* # 

     self.myGrid2 = gridlib.Grid(self.panel) 
     self.myGrid2.CreateGrid(2, 6) 

     for i in range(6): 
      self.myGrid2.SetColSize(i, 60) 

     self.myGrid2.SetColLabelValue(0, "") 
     self.myGrid2.SetColLabelValue(1, "Yesterday") 
     self.myGrid2.SetColLabelValue(2, "") 
     self.myGrid2.SetColLabelValue(3, "") 
     self.myGrid2.SetColLabelValue(4, "Today") 
     self.myGrid2.SetColLabelValue(5, "") 

     self.myGrid2.SetCellValue(0, 0, "Treasury") 
     self.myGrid2.SetCellValue(0, 1, "Volatility") 
     self.myGrid2.SetCellValue(0, 2, "Cash") 
     self.myGrid2.SetCellValue(0, 3, "Treasury") 
     self.myGrid2.SetCellValue(0, 4, "Volatility") 
     self.myGrid2.SetCellValue(0, 5, "Cash") 

     self.myGrid2.SetRowLabelSize(60) 
     self.myGrid2.SetRowLabelValue(0, "") 
     self.myGrid2.SetRowLabelValue(1, "ABRXIV") 

     self.myGrid2.SetColLabelAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) 
     self.myGrid2.SetDefaultCellAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP) 
     # ****************************** # 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.myGrid1, 1, wx.TOP|wx.ALIGN_CENTRE, 2) 
     sizer.Add(self.myGrid2, 1, wx.TOP|wx.ALIGN_CENTRE, 2) 
     sizer.Add(button_refresh, 1, wx.RIGHT|wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND|wx.ALIGN_CENTRE, 50) 

     self.panel.SetSizer(sizer) 
     self.panel.SetSize((500,400)) 
     self.SetSize((500,400)) 
     self.panel.Layout() 

    def refresh(self, event): 
     pass 

if __name__ == "__main__": 
    app = wx.App() 
    frame = MyForm().Show() 
    app.MainLoop() 
+0

不知道你的意思。你能用网格中的数据给你一些截图吗? – Igor

+0

@Igor我添加了一个截图来显示我想要的。 –

回答

2

快速而肮脏的方法是转储列标签SetColLabelSize(0)并将标题添加为单元格。
然后调整单元跨度为SetCellSize()的那些单元格。
下面我改变了myGrid1,但不是myGrid2。

import wx 
import wx.grid as gridlib 

class MyForm(wx.Frame): 
    def __init__(self): 
     """Constructor""" 
     wx.Frame.__init__(self, parent=None, title="Strategies' Allocations") 
     self.panel = wx.Panel(self) 

     button_refresh = wx.Button(self.panel, id=wx.ID_ANY, label='Refresh') 
     button_refresh.Bind(wx.EVT_BUTTON, self.refresh) 

     self.myGrid1 = gridlib.Grid(self.panel) 
     self.myGrid1.CreateGrid(3, 6) 

     self.myGrid1.SetRowLabelSize(80) 
     self.myGrid1.SetRowLabelValue(0, "") 
     self.myGrid1.SetRowLabelValue(1, "") 
     self.myGrid1.SetRowLabelValue(2, "2") 

     for i in range(6): 
      self.myGrid1.SetColSize(i, 60) 

#  self.myGrid1.SetColLabelValue(0, "") 
#  self.myGrid1.SetColLabelValue(1, "Yesterday") 
#  self.myGrid1.SetColLabelValue(2, "") 
#  self.myGrid1.SetColLabelValue(3, "") 
#  self.myGrid1.SetColLabelValue(4, "Today") 
#  self.myGrid1.SetColLabelValue(5, "") 

     self.myGrid1.SetColLabelSize(0) 
     self.myGrid1.SetCellSize(0, 0, 1, 3) 
     self.myGrid1.SetCellValue(0, 0, "Yesterday") 
     self.myGrid1.SetCellSize(0, 3, 1, 3) 
     self.myGrid1.SetCellValue(0, 3, "Today") 

     self.myGrid1.SetCellValue(1, 0, "Equity") 
     self.myGrid1.SetCellValue(1, 1, "Volatility") 
     self.myGrid1.SetCellValue(1, 2, "Cash") 
     self.myGrid1.SetCellValue(1, 3, "Equity") 
     self.myGrid1.SetCellValue(1, 4, "Volatility") 
     self.myGrid1.SetCellValue(1, 5, "Cash") 

     self.myGrid1.SetColLabelAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) 
     self.myGrid1.SetDefaultCellAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP) 
     # ******************************* # 

     self.myGrid2 = gridlib.Grid(self.panel) 
     self.myGrid2.CreateGrid(2, 6) 

     for i in range(6): 
      self.myGrid2.SetColSize(i, 60) 

     self.myGrid2.SetColLabelValue(0, "") 
     self.myGrid2.SetColLabelValue(1, "Yesterday") 
     self.myGrid2.SetColLabelValue(2, "") 
     self.myGrid2.SetColLabelValue(3, "") 
     self.myGrid2.SetColLabelValue(4, "Today") 
     self.myGrid2.SetColLabelValue(5, "") 

     self.myGrid2.SetCellValue(0, 0, "Treasury") 
     self.myGrid2.SetCellValue(0, 1, "Volatility") 
     self.myGrid2.SetCellValue(0, 2, "Cash") 
     self.myGrid2.SetCellValue(0, 3, "Treasury") 
     self.myGrid2.SetCellValue(0, 4, "Volatility") 
     self.myGrid2.SetCellValue(0, 5, "Cash") 

     self.myGrid2.SetRowLabelSize(60) 
     self.myGrid2.SetRowLabelValue(0, "") 
     self.myGrid2.SetRowLabelValue(1, "2") 

     self.myGrid2.SetColLabelAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) 
     self.myGrid2.SetDefaultCellAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP) 
     # ****************************** # 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.myGrid1, 1, wx.TOP|wx.ALIGN_CENTRE, 2) 
     sizer.Add(self.myGrid2, 1, wx.TOP|wx.ALIGN_CENTRE, 2) 
     sizer.Add(button_refresh, 1, wx.RIGHT|wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND|wx.ALIGN_CENTRE, 50) 

     self.panel.SetSizer(sizer) 
     self.panel.SetSize((500,400)) 
     self.SetSize((500,400)) 
     self.panel.Layout() 

    def refresh(self, event): 
     pass 

if __name__ == "__main__": 
    app = wx.App() 
    frame = MyForm().Show() 
    app.MainLoop() 

enter image description here

+0

因为我正在努力做到这一点,所以完成了这项工作。谢谢您的帮助。 –

+0

@AlexF在您对两个答案进行编辑之后,我已添加回调整图像。如果仍然存在隐私问题,请随时重新编辑。 –

+0

这太好了。对那些需要它的人仍然很有帮助,但保持隐私。感谢您的包容。 –

1

这不会是特别简单的,但我认为你应该达到你想要的东西从wxGridCellAttrProvider定义一个类派生并重写其GetColumnHeaderRenderer()方法返回一个“什么都不做” wxGridColumnHeaderRenderer你想要的列合并,并为其他标准渲染器(由基类GetColumnHeaderRenderer()返回)。然后你只需要在你的表对象上用你自定义的属性提供者对象调用SetAttrProvider()

2

看看在wxPython中演示的GridLabelRenderer样品。这是根据wx.lib.mixins.gridlabelrenderer中的类为网格行和列绘制自定义标签的示例。使用这些类可以非常容易地根据需要绘制标签。您只需要重写相应的Draw方法。

0

正如@RobinDunn所建议的那样,这里是一个使用GridLabelRenderer的版本(排序),它不像第一次看起来那么复杂。
但是,它确实有一些奇怪的地方。
请注意使用lr来存储rect.leftrect.right
这样做是因为如果你调整rect.leftright.right也可以调整,而不需要你这样做。
我认为这是因为rect有一个大小,所以如果你调整1个元素,另一个补偿。
还要注意,您必须声明空白列标题,否则它们将恢复为标准的“A,B,C,D .....”序列。

import wx 
import wx.grid as grid 
import wx.lib.mixins.gridlabelrenderer as glr 
#---------------------------------------------------------------------- 
class MyGrid(grid.Grid, glr.GridWithLabelRenderersMixin): 
    def __init__(self, *args, **kw): 
     grid.Grid.__init__(self, *args, **kw) 
     glr.GridWithLabelRenderersMixin.__init__(self) 

class TextLabelRenderer(glr.GridLabelRenderer): 
    def __init__(self, text, colspan,bgcolour=None): 
     self.text = text 
     self.colspan = colspan 
     if bgcolour is not None: 
      self.bgcolour = bgcolour 
     else: 
      self.bgcolour = "white" 

    def Draw(self, grid, dc, rect, col): 
     if self.colspan == 0: 
      rect.SetSize((0,0)) 
     if self.colspan > 1: 
      add_cols = self.colspan - 1 
      l = rect.left 
      r = rect.right + ((rect.Size.x -1) * add_cols) 
      rect.left = l 
      rect.right = r 
     dc.SetBrush(wx.Brush(self.bgcolour)) 
     dc.SetPen(wx.TRANSPARENT_PEN) 
     dc.DrawRectangleRect(rect) 
     hAlign, vAlign = grid.GetColLabelAlignment() 
     text = self.text 
     if self.colspan != 0: 
      self.DrawBorder(grid, dc, rect) 
     self.DrawText(grid, dc, rect, text, hAlign, vAlign) 

class TestPanel(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, parent=None, size=(800,300)) 
     ROWS = 6 
     COLS = 11 
     g = MyGrid(self, size=(100,100)) 
     g.CreateGrid(ROWS, COLS) 
     g.SetColLabelRenderer(0, TextLabelRenderer('Contract',1,"lightblue")) 
     g.SetColLabelRenderer(1, TextLabelRenderer('Yesterday',3,"lightgreen")) 
     g.SetColLabelRenderer(2, TextLabelRenderer('',0)) 
     g.SetColLabelRenderer(3, TextLabelRenderer('',0)) 
     g.SetColLabelRenderer(4, TextLabelRenderer('Today',4,"green")) 
     g.SetColLabelRenderer(5, TextLabelRenderer('',0)) 
     g.SetColLabelRenderer(6, TextLabelRenderer('',0)) 
     g.SetColLabelRenderer(7, TextLabelRenderer('',0)) 
     g.SetColLabelRenderer(8, TextLabelRenderer('Other',1,"gold")) 
     # g.SetColLabelRenderer(9, TextLabelRenderer('',0)) 
     g.SetRowLabelSize(0) 
     g.SetCellValue(0, 1, "Equity") 
     g.SetCellValue(0, 2, "Volatility") 
     g.SetCellValue(0, 3, "Cash") 
     g.SetCellValue(0, 4, "Equity") 
     g.SetCellValue(0, 5, "Volatility") 
     g.SetCellValue(0, 6, "Cash") 
     g.SetCellValue(1, 0, "2") 
     g.SetCellValue(1, 1, "1500") 
     g.SetCellValue(1, 2, "23") 
     g.SetCellValue(1, 3, "2300") 
     g.SetCellValue(1, 4, "1400") 
     g.SetCellValue(1, 5, "26") 
     g.SetCellValue(1, 6, "2400") 
     g.SetColLabelAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) 
     g.SetDefaultCellAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP) 

     g1 = MyGrid(self, size=(100,100)) 
     g1.CreateGrid(ROWS, COLS) 
     g1.SetColLabelRenderer(0, TextLabelRenderer('Contract',1,"lightblue")) 
     g1.SetColLabelRenderer(1, TextLabelRenderer('Yesterday',3,"lightgreen")) 
     g1.SetColLabelRenderer(2, TextLabelRenderer('',0)) 
     g1.SetColLabelRenderer(3, TextLabelRenderer('',0)) 
     g1.SetColLabelRenderer(4, TextLabelRenderer('Today',3,"green")) 
     g1.SetColLabelRenderer(5, TextLabelRenderer('',0)) 
     g1.SetColLabelRenderer(6, TextLabelRenderer('',0)) 
     g1.SetColLabelRenderer(7, TextLabelRenderer('Other',2,"gold")) 
     g1.SetColLabelRenderer(8, TextLabelRenderer('',0)) 
     g1.SetRowLabelSize(0) 
     g1.SetCellValue(0, 1, "Equity") 
     g1.SetCellValue(0, 2, "Volatility") 
     g1.SetCellValue(0, 3, "Cash") 
     g1.SetCellValue(0, 4, "Equity") 
     g1.SetCellValue(0, 5, "Volatility") 
     g1.SetCellValue(0, 6, "Cash") 
     g1.SetCellValue(1, 0, "2") 
     g1.SetCellValue(1, 1, "500") 
     g1.SetCellValue(1, 2, "23") 
     g1.SetCellValue(1, 3, "12300") 
     g1.SetCellValue(1, 4, "11400") 
     g1.SetCellValue(1, 5, "26") 
     g1.SetCellValue(1, 6, "12400") 
     g1.SetColLabelAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE) 
     g1.SetDefaultCellAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP) 
     self.Sizer = wx.BoxSizer(wx.VERTICAL) 
     self.Sizer.Add(g, 1, wx.EXPAND) 
     self.Sizer.Add(g1, 1, wx.EXPAND) 
     self.Show() 
#---------------------------------------------------------------------- 
if __name__ == "__main__": 
    app = wx.App() 
    frame = TestPanel() 
    app.MainLoop() 

enter image description here