【问题标题】:wxPython - grid.AutoSizeColumns() doesn't apply to the index column?wxPython - grid.AutoSizeColumns() 不适用于索引列?
【发布时间】:2021-05-14 01:31:46
【问题描述】:

我的结果框中显示了一个分析结果网格,创建网格对象后,我调用grid.AutoSizeColumns() 以使列适合数据内容。这适用于包含数据的实际列,但仅包含行索引的最左边的列(“索引”列?)仍然相当宽——比需要的宽得多,因为只有四行。 我想做的事: - 删除最左边的列(仅包含行索引的灰色列),和/或 -删除实际“索引”列(带有标题“索引”),因为它是多余的,并缩小最左边的灰色列,或者 - 删除最左边的列和标有“索引”的列。

注意:我知道grid.DeleteCols(pos=0, numCols=1) 方法,但这总是会引发错误:

wx._core.wxAssertionError: C++ assertion ""Assert failure"" failed at ..\..\src\generic\grid.cpp(1471) in wxGridTableBase::DeleteCols(): Called grid table class function DeleteCols
but your derived table class does not override this function

我不确定如何“覆盖此功能”。如果有人可以向我解释错误/如何修复它以便grid.DeleteCols() 起作用,那将是解决我的问题的一半(另一半正在缩小或删除网格中最左侧的灰色列)

下面的最小代码示例,以及当前外观的屏幕截图(取自实际程序,而不是最小代码)

在相关说明中,是否有一种简单的方法可以右对齐网格中的单元格值?我将结果格式化为所有的小数位数相同,我认为如果值右对齐(甚至居中)会看起来更整洁。

小例子:

import wx
import wx.grid
import numpy as np
import pandas as pd

class StartFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent=parent,
         id=wx.ID_ANY, title="title", size=wx.Size(900,600),
         style=wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.RESIZE_BORDER)
        self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)

        self.numarray=[[1,0.0000,0.071,3.535,3.313,0.22],
                       [10,1.000,0.071,3.535,3.888,-0.353],
                       [20,1.301,0.357,4.634,4.526,0.108],
                       [50,1.699,0.929,6.456,6.442,0.023]]
        self.df = pd.DataFrame(self.numarray, columns=['Parasites/ml','log_qty',
         'probability','probit','est. probit','residual'])

        self.table = DataTable(self.df)
        grid = wx.grid.Grid(self, -1)
        grid.SetTable(self.table, takeOwnership=True)
        grid.AutoSizeColumns()

        self.pnl = wx.Panel(self)
        self.vsizer = wx.BoxSizer(wx.VERTICAL)
        self.hsizer = wx.BoxSizer(wx.HORIZONTAL)

        self.hsizer.AddStretchSpacer()
        self.hsizer.Add(grid, 0, wx.CENTER)
        self.hsizer.AddStretchSpacer()
        self.vsizer.AddStretchSpacer()
        self.vsizer.Add(self.hsizer, wx.SizerFlags().Expand().Border(wx.ALL, 5))
        self.vsizer.AddStretchSpacer()
        self.pnl.SetSizerAndFit(self.vsizer)

class DataTable(wx.grid.GridTableBase):
    def __init__(self, printdata=None):
        wx.grid.GridTableBase.__init__(self)
        self.headerRows = 1
        if printdata is None: data = pd.DataFrame()
        self.data = printdata

    def GetNumberRows(self):
        return len(self.data)

    def GetNumberCols(self):
        return len(self.data.columns) + 1

    def GetValue(self, row, col):
        if col == 0: return self.data.index[row]
        return self.data.iloc[row, col - 1]

    def SetValue(self, row, col, value):
        self.data.iloc[row, col - 1] = value

    def GetColLabelValue(self, col):
        if col == 0:
            if self.data.index.name is None: return 'Index'
            else: return self.data.index.name
        return str(self.data.columns[col - 1])

def main():
    app = wx.App()
    frm = StartFrame(None)
    frm.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()

【问题讨论】:

    标签: python-3.x wxpython


    【解决方案1】:

    您可以Hide Columns 和/或Rows,因此这是一种处理错误左侧列的简单方法。

    Hide 对其他事情也很有用,例如grid.HideRowLabels(),会隐藏左边那些讨厌的行号。

    对齐问题可能可以通过使用wx.grid.GridCellAttrProvider 来处理,或者您可以简单地遍历设置每个单元格的网格,为简单起见,我在下面做了。

    import wx
    import wx.grid
    import numpy as np
    import pandas as pd
    
    class StartFrame(wx.Frame):
        def __init__(self, parent):
            wx.Frame.__init__(self, parent=parent,
             id=wx.ID_ANY, title="title", size=wx.Size(900,600),
             style=wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.RESIZE_BORDER)
            self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
    
            self.numarray=[[1,0.0000,0.071,3.535,3.313,0.22],
                           [10,1.000,0.071,3.535,3.888,-0.353],
                           [20,1.301,0.357,4.634,4.526,0.108],
                           [50,1.699,0.929,6.456,6.442,0.023]]
            self.df = pd.DataFrame(self.numarray, columns=['Parasites/ml','log_qty',
             'probability','probit','est. probit','residual'])
    
            self.table = DataTable(self.df)
            grid = wx.grid.Grid(self, -1)
            grid.SetTable(self.table, takeOwnership=True)
            # Hide Index column
            grid.HideCol(0)
            grid.HideRowLabels()
            # Alignment of cells
            r = grid.GetNumberRows()
            c = grid.GetNumberCols()
            for row in range(r):
                for cell in range(c):
                    grid.SetCellAlignment(row, cell, wx.ALIGN_RIGHT, wx.ALIGN_CENTER)
            grid.AutoSizeColumns()
            self.pnl = wx.Panel(self)
            self.vsizer = wx.BoxSizer(wx.VERTICAL)
            self.hsizer = wx.BoxSizer(wx.HORIZONTAL)
    
            self.hsizer.AddStretchSpacer()
            self.hsizer.Add(grid, 0, wx.CENTER)
            self.hsizer.AddStretchSpacer()
            self.vsizer.AddStretchSpacer()
            self.vsizer.Add(self.hsizer, wx.SizerFlags().Expand().Border(wx.ALL, 5))
            self.vsizer.AddStretchSpacer()
            self.pnl.SetSizerAndFit(self.vsizer)
    
    class DataTable(wx.grid.GridTableBase):
        def __init__(self, printdata=None):
            wx.grid.GridTableBase.__init__(self)
            self.headerRows = 1
            if printdata is None: data = pd.DataFrame()
            self.data = printdata
    
        def GetNumberRows(self):
            return len(self.data)
    
        def GetNumberCols(self):
            return len(self.data.columns) + 1
    
        def GetValue(self, row, col):
            if col == 0: return self.data.index[row]
            return self.data.iloc[row, col - 1]
    
        def SetValue(self, row, col, value):
            self.data.iloc[row, col - 1] = value
    
        def GetColLabelValue(self, col):
            if col == 0:
                if self.data.index.name is None: return 'Index'
                else: return self.data.index.name
            return str(self.data.columns[col - 1])
    
    def main():
        app = wx.App()
        frm = StartFrame(None)
        frm.Show()
        app.MainLoop()
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 非常感谢!这绝对是一个巨大的帮助。在使用 wx.Grid 对象时,最左边的列只是生活中的事实吗?如果我可以摆脱它,我真的很想 - 但如果它就在那里并且没有什么可做的,我会继续并标记你的答案是正确的。干杯!
    • @W.MacTurk 答案已编辑以隐藏行标签
    • 啊,对不起,我的错!在重新对齐单元格值并隐藏“索引”列的兴奋中,我忘记尝试将Hide() 应用于行标签列。非常感谢接受:)
    猜你喜欢
    • 2020-08-07
    • 2015-10-30
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    相关资源
    最近更新 更多