如何在wxPython选项卡中显示Pandas数据帧



我正试图在wxPython选项卡中显示pandas数据框。我尝试过其他方法,比如在ListCtrl中使用wxPython的内部版本,但无法实现,我认为使用DataFrame会更容易。

经过一点研究,这段代码似乎可以在自己的上工作

import json
import pandas as pd
from IPython.core.display import display
df = pd.DataFrame(data["downloadHistory"][0])
display(df)

输出:

titles   author                 urls
0  exampletitle1  author1  https://example.com
1  exampletitle2  author2  https://example.com

但是当在下面的选项卡中时,输出看起来就不那么漂亮了。

class DownloadHistory(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
df = pd.DataFrame(data["downloadHistory"][0])
disp = display(df)
doHiLab = wx.StaticText(self, -1, "DOWNLOAD HISTORY:", (10, 15))
tableText = wx.StaticText(self, -1, str(disp), (10, 50))
self.clear = wx.Button(self, label='Clear History', size=(75, 25), pos=(420, 10))

输出示例1:

titles author         urls
0  exampletitle1  author1  https://example.com
1  exampletitle2  author2  https://example.com

Ouput示例2:

titles  author           urls
0  example123456789  author123456  https://example.com/
1   exampletitle2   author2  https://example.com/12345

JSON文件:

{
"downloadHistory": [
{
"titles": ["example123456789", "exampletitle2"],
"author": ["author123456", "author2"],
"urls": ["https://example.com/", "https://example.com/12345"]
}
],
}

有没有什么原因可以解释为什么选项卡中的输出很乱,而不是它自己?

此外,有没有一种有效的方法可以在wxPython中显示DataFrame?

我试着研究了更多,但没有成功。

你走在了正确的轨道上。有很多选择。我建议您将DataFrame分配给wx.grid,该网格显示行和列对齐。

使用下载历史JSON文件:

import pandas as pd
import wx
import wx.grid
EVEN_ROW_COLOUR = '#CCE6FF'
GRID_LINE_COLOUR = '#ccc'
data = {
"downloadHistory": [
{
"titles": ["example123456789", "exampletitle2"],
"author": ["author123456", "author2"],
"urls": ["https://example.com/", "https://example.com/12345"]
}
],
}
#declare DataTable to hold the wx.grid data to be displayed
class DataTable(wx.grid.GridTableBase):
def __init__(self, data=None):
wx.grid.GridTableBase.__init__(self)
self.headerRows = 1
if data is None:
data = pd.DataFrame()
self.data = data
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 GetTypeName(self, row, col):
return wx.grid.GRID_VALUE_STRING
def GetAttr(self, row, col, prop):
attr = wx.grid.GridCellAttr()
if row % 2 == 1:
attr.SetBackgroundColour(EVEN_ROW_COLOUR)
return attr

class MyFrame(wx.Frame):
"""
Frame that holds all other widgets
"""
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, wx.ID_ANY, "DOWNLOAD HISTORY")
self._init_gui()
self.Layout()
self.Show()
def _init_gui(self):
# assign the DataFrame to df
df = pd.DataFrame(data["downloadHistory"][0])
table = DataTable(df)
#declare the grid and assign data
grid = wx.grid.Grid(self, -1)
grid.SetTable(table, takeOwnership=True)
grid.AutoSizeColumns()
mainSizer = wx.BoxSizer(wx.VERTICAL)
sizer = wx.BoxSizer(wx.HORIZONTAL)

sizer.Add(grid, 0, wx.EXPAND)
#add some buttons, and change methods as needed
cancelButton = wx.Button(self, wx.ID_CANCEL, "Cancel")
self.Bind(wx.EVT_BUTTON, self.OnCancel, cancelButton)
proceedButton = wx.Button(self, wx.ID_OK, "Proceed")
self.Bind(wx.EVT_BUTTON, self.OnProceed, proceedButton)
sizerbtns = wx.BoxSizer(wx.HORIZONTAL)
sizerbtns.Add(cancelButton, 0, wx.CENTER)
sizerbtns.Add(proceedButton, 0, wx.CENTER)

mainSizer.Add(sizer, 0, wx.ALL, 5)
mainSizer.Add(sizerbtns, 0, wx.CENTER)

sizer.SetSizeHints(self)
self.SetSizerAndFit(mainSizer)
self.Bind(wx.EVT_CLOSE, self.exit)
def exit(self, event):
self.Destroy()
def OnCancel(self, event):
self.Destroy()

def OnProceed(self, event):
self.Destroy()
if __name__ == "__main__":
app = wx.App()
frame = MyFrame()
app.MainLoop()

最新更新