pythonpython-3.xpandaspyscripterwxglade

Pandas dataframe import to WxGlade GUI


I have been experimenting using DataFrames within a GUI but I'm having some trouble which is really annoying. My code runs but I just can't see what I'm missing to get my DataFrame to display in my GUI. I've created the grid and styles but it won't pull data.

Can you help show me what I am missing please.

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# generated by wxGlade 0.9.3 on Tue Apr  9 09:46:29 2019
#

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

#colors

EVEN_ROW_COLOUR = '#CCE6FF'
GRID_LINE_COLOUR = '#ccc'

# begin wxGlade: dependencies
# end wxGlade

# begin wxGlade: extracode
# end wxGlade


class MySD_Frame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MySD_Frame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((1289, 685))
        self.button_6 = wx.Button(self, wx.ID_ANY, "button_6")
        self.button_7 = wx.Button(self, wx.ID_ANY, "button_7")
        self.button_8 = wx.Button(self, wx.ID_ANY, "button_8")
        self.button_11 = wx.Button(self, wx.ID_ANY, "button_11")
        self.button_9 = wx.Button(self, wx.ID_ANY, "button_9")
        self.button_10 = wx.Button(self, wx.ID_ANY, "button_10")
        self.MyTable = wx.grid.Grid(self, wx.ID_ANY, size=(1, 1))

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: MySD_Frame.__set_properties
        self.SetTitle("frame")
        self.SetBackgroundColour(wx.Colour(50, 58, 114))
       # self.GridTableBase.
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MySD_Frame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_9 = wx.BoxSizer(wx.VERTICAL)
        sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_3 = wx.BoxSizer(wx.VERTICAL)
        sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_1 = wx.GridSizer(1, 9, 0, 0)
        sizer_15 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_14 = wx.BoxSizer(wx.HORIZONTAL)
        bitmap_1 = wx.StaticBitmap(self, wx.ID_ANY, wx.Bitmap('PNG PATH', wx.BITMAP_TYPE_ANY))
        sizer_3.Add(bitmap_1, 0, wx.ALIGN_CENTER, 0)
        sizer_14.Add((20, 0), 0, 0, 0)
        sizer_14.Add(self.button_6, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(sizer_14, 1, wx.EXPAND, 0)
        grid_sizer_1.Add(self.button_7, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.button_8, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.button_11, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add((0, 0), 0, 0, 0)
        grid_sizer_1.Add(self.button_9, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0)
        sizer_15.Add((40, 20), 0, 0, 0)
        sizer_15.Add(self.button_10, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0)
        sizer_15.Add((20, 20), 0, 0, 0)
        grid_sizer_1.Add(sizer_15, 1, wx.EXPAND, 0)
        sizer_5.Add(grid_sizer_1, 1, wx.EXPAND, 0)
        sizer_4.Add(sizer_5, 1, wx.EXPAND, 0)
        sizer_3.Add(sizer_4, 1, wx.EXPAND, 0)
        sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
        sizer_10.Add((20, 20), 0, 0, 0)
        sizer_10.Add(self.MyTable, 1, wx.EXPAND, 0)
        sizer_10.Add((20, 20), 0, 0, 0)
        sizer_9.Add(sizer_10, 1, wx.EXPAND, 0)
        sizer_9.Add((20, 60), 0, 0, 0)
        sizer_6.Add(sizer_9, 1, wx.EXPAND, 0)
        sizer_2.Add(sizer_6, 1, wx.EXPAND, 0)
        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()
        # end wxGlade

# end of class MySD_Frame



class DataTable(wx.grid.GridTableBase):
    def __init__(self, data=None):
        wx.grid.GridTableBase.__init__(self)
        self.headerRows = 1
        if data is None:
            data = pd.read_excel('EXCEL PATH')
        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


    def _init_gui(self):
        df = pd.read_excel('EXCEL PAT')
        table = DataTable(df)

        self.table = DataTable(df)
        self.frame.MyTable.SetTable(self.table, takeOwnership=True)
        grid.AutoSizeColumns()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(grid, 1, wx.EXPAND)
        self.SetSizer(sizer)

        self.Bind(wx.EVT_CLOSE, self.exit)



class MyApp(wx.App):
    def OnInit(self):
        self.frame = MySD_Frame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

        wx.Frame.__init__(self, None, wx.ID_ANY, "Pandas")
        self._init_gui()
        self.Layout()
        self.Show()

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

I originally built this with tkinter but I had that much frustration and moved to wxglade. now the code runs and gui displays with the data table just seems to be missing data.

Disappointed... guess you have to be a C# programmer to gain any help around here because the python community seems so limited. For anyone wondering I have read, looked and watched videos on the area which is and I've had several error reports when trying to resolve this but always seem to come back to this one when stepping through and resolving the class issues.

  File "This code", line 66, in __do_layout
    sizer_7 = wx.grid.MyTable(self.ExcelSheet1)
TypeError: wx._grid.MyTable represents a C++ abstract class and cannot be instantiated

(I'm no long throwing this error, but grid still doesn't init)

Again...Any help would be grateful


Solution

  • Using 'GridTableBase' as name for the grid is a really strange choice.

    Anyway, after creating the frame including the grid:

        self.table = DataTable(df)
        self.frame.GridTableBase.SetTable(self.table, takeOwnership=True)
    

    wxPython's grid demos GridCustTable.py or GridHugeTable.py should have enough examples how to create virtual grids.