问题描述
我正在尝试在wxPython选项卡中显示熊猫数据框。 我尝试了其他方法,例如在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,str(disp),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
输出示例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,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,col):
return wx.grid.GRID_VALUE_STRING
def GetAttr(self,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,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,wx.CENTER)
sizerbtns.Add(proceedButton,wx.CENTER)
mainSizer.Add(sizer,wx.ALL,5)
mainSizer.Add(sizerbtns,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()