在wxpython中的面板之间传递信息

时间:2018-01-12 00:37:57

标签: python python-2.7 wxpython

我有一个非常复杂的wxpython应用程序,它有嵌套的笔记本和面板。基本上结构是在我的主框架中我有一个笔记本(比如笔记本1,在笔记本的一页我有两个面板(上面和下面)。在下面板我有另一个笔记本(比如笔记本2)。所以问题是如何在这两个笔记本页面和上面板之间传递信息。

我知道基本上有三种传递信息的方式:事件id,发布者,.parent和.child。但是我真的很困惑这三种方法的区别以及何时使用它们。

我附上了我的代码,如下所示。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import datetime, time
import wx, sys, wx.grid
import xlrd

import pandas as pd
import numpy as np
import wx.lib.scrolledpanel as scrolled

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

import pandas as pd
import numpy as np

class ResultTable(wx.grid.PyGridTableBase):
    def __init__(self, data=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.odd=wx.grid.GridCellAttr()
        self.odd.SetBackgroundColour("sky blue")
        self.odd.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
        self.even=wx.grid.GridCellAttr()
        self.even.SetBackgroundColour("sea green")
        self.even.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))

    def GetNumberRows(self):
        return self.data.shape[0]
    def GetNumberCols(self):
        return self.data.shape[1]
    def GetValue(self, row, col):
        return self.data.loc[row][col]
    def GetColLabelValue(self, row):
        return list(self.data)[row]
    def SetValue(self, row, col, value):
        pass
    def GetAttr(self, row, col, prop):
        attr = wx.grid.GridCellAttr()
        if row % 2 == 1:
            attr.SetBackgroundColour(EVEN_ROW_COLOUR)
        return attr

class ResultTablePanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
        grid = wx.grid.Grid(self)


        result = pd.DataFrame({'a' : np.random.randn(100), 'b' : np.random.randn(100), 'c' : np.random.randn(100)})

        table = ResultTable(result)
        grid.SetTable(table)

        grid.AutoSize()
        grid.AutoSizeColumns(True)
        grid.SetGridLineColour(GRID_LINE_COLOUR)

        grid.EnableDragGridSize( False )

        grid.SetRowLabelSize( 50 )
        grid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )

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

        btn_ID = parent.GetParent().GetParent().topPanel.analysisButton.GetId()
        self.Bind(wx.EVT_BUTTON, self.getResult, id = btn_ID)

    def getResult(self,e):
        """
        This function should get the variables passed by the analysisOrder function,
        once the button on the SearchConditionPanel is clicked.
        """
        fileName, start_date, end_date = parent.GetParent().GetParent().topPanel.analysisOrder
        print "result get as follows:"
        print fileName, start_date, end_date



class SearchConditionPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)

        # Creat input box for searching time period
        nameTitleLable = wx.StaticText(self,-1, label=u"File Name:")
        self.fileNameInput = wx.TextCtrl(self,-1, "20170310221612")

        dateTitleLable = wx.StaticText(self,-1, label=u"Date range:")
        yearLable1 = wx.StaticText(self, label=u"Year:")
        monthLable1 = wx.StaticText(self,-1, label=u"Month:")
        dayLable1 = wx.StaticText(self,-1, label=u"Day:")
        yearLable2 = wx.StaticText(self,-1, label=u"Year:")
        monthLable2 = wx.StaticText(self,-1, label=u"Month:")
        dayLable2 = wx.StaticText(self,-1, label=u"Day:")
        startLable = wx.StaticText(self,-1, label=u"Start Date:")
        endLable = wx.StaticText(self,-1, label=u"End Date:")
        self.startYearInput = wx.TextCtrl(self,1, "2016")
        self.startMonthInput = wx.TextCtrl(self,-1, "10")
        self.startDayInput = wx.TextCtrl(self,-1, "30")
        self.endYearInput = wx.TextCtrl(self,-1, "2017")
        self.endMonthInput = wx.TextCtrl(self,-1, "11")
        self.endDayInput = wx.TextCtrl(self,-1, "22")

        self.analysisButton = wx.Button(self, -1, label = u'Start')
        exportButton = wx.Button(self, -1, label = u'Export')
        exportButton.Disable()

        ## Set up overall layout for the panel
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        vbox_File_button = wx.BoxSizer(wx.VERTICAL)
        hbox_file = wx.BoxSizer(wx.HORIZONTAL)
        vbox_date = wx.BoxSizer(wx.VERTICAL)
        hbox_button = wx.BoxSizer(wx.HORIZONTAL)
        hbox_startDate = wx.BoxSizer(wx.HORIZONTAL)
        hbox_endDate = wx.BoxSizer(wx.HORIZONTAL)

        hbox.Add(vbox_date, 0, wx.ALIGN_LEFT | wx.ALL, 5)
        hbox.Add(wx.StaticLine(self, style=wx.LI_VERTICAL), 0, wx.ALL | wx.EXPAND, 5)
        hbox.Add(vbox_File_button, 0, wx.ALIGN_LEFT | wx.ALL, 5)

        ## Setup the layout for the right side
        vbox_File_button.Add(hbox_file, 0, wx.ALIGN_LEFT | wx.ALL, 5)
        vbox_File_button.Add(wx.StaticLine(self), 0, wx.ALL | wx.EXPAND, 5)
        vbox_File_button.Add(hbox_button, 0, wx.ALIGN_LEFT | wx.ALL, 5)

        hbox_file.Add(nameTitleLable, 0, wx.TOP | wx.LEFT | wx.BOTTOM, 10)
        hbox_file.Add(self.fileNameInput, 0, wx.ALL | wx.EXPAND, 5)

        hbox_button.Add(self.analysisButton, 1, wx.TOP | wx.LEFT, 10)
        hbox_button.Add(exportButton, 1, wx.TOP | wx.LEFT, 10)

        ## Setup the layout for the left side
        vbox_date.Add(dateTitleLable, 0, wx.ALL, 5)
        vbox_date.Add(hbox_startDate, 0, wx.ALL | wx.EXPAND, 5)
        vbox_date.Add(hbox_endDate, 0, wx.ALL | wx.EXPAND, 5)

        hbox_startDate.Add(startLable, 0, wx.ALL, 5)
        hbox_startDate.Add(yearLable1, 0, wx.TOP | wx.LEFT | wx.BOTTOM, 5)
        hbox_startDate.Add(self.startYearInput, 0, wx.ALL, 5)
        hbox_startDate.Add(monthLable1, 0, wx.TOP | wx.LEFT | wx.BOTTOM, 5)
        hbox_startDate.Add(self.startMonthInput, 0, wx.ALL|wx.EXPAND, 5)
        hbox_startDate.Add(dayLable1, 0, wx.TOP | wx.LEFT | wx.BOTTOM, 5)
        hbox_startDate.Add(self.startDayInput, 0, wx.ALL|wx.EXPAND, 5)

        hbox_endDate.Add(endLable, 0, wx.LEFT | wx.RIGHT, 5)
        hbox_endDate.Add(yearLable2, 0, wx.LEFT, 5)
        hbox_endDate.Add(self.endYearInput, 0, wx.LEFT | wx.RIGHT, 5)
        hbox_endDate.Add(monthLable2, 0, wx.LEFT, 5)
        hbox_endDate.Add(self.endMonthInput, 0, wx.LEFT | wx.RIGHT, 5)
        hbox_endDate.Add(dayLable2, 0, wx.LEFT, 5)
        hbox_endDate.Add(self.endDayInput, 0, wx.LEFT, 5)

        self.SetSizer(hbox)

        self.Bind(wx.EVT_BUTTON, self.analysisOrder, id=self.analysisButton.GetId())


    def analysisOrder(self,e):
        fileName_temp = self.fileNameInput.GetValue().strip()
        fileName = fileName_temp + '.xls'
        start_date = self.startYearInput.GetValue().strip() + '-' + self.startMonthInput.GetValue().strip() + '-' + self.startDayInput.GetValue().strip()
        end_date = self.endYearInput.GetValue().strip() + '-' + self.endMonthInput.GetValue().strip() + '-' + self.endDayInput.GetValue().strip()

        print "analysis order button called"

        return fileName, start_date, end_date


class ResultNotebook(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        # Creat notebooks for window layout
        result_notebook = wx.Notebook(self)

        data_page = ResultTablePanel(result_notebook, -1)

        result_notebook.AddPage(data_page, u"Display Data")

        # Set up a boxsizer for the tabs
        result_notebook_sizer = wx.BoxSizer(wx.HORIZONTAL)
        result_notebook_sizer.Add(result_notebook, 1, wx.EXPAND)
        self.SetSizer(result_notebook_sizer)

class ModePage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        # Localize all the panels
        self.topPanel = SearchConditionPanel(self, -1)
        self.botPanel = ResultNotebook(self)

        #Set up the panels, align and position them in the right place
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.topPanel, 0, wx.EXPAND | wx.ALL, 5)
        vbox.Add(self.botPanel, -1, wx.EXPAND | wx.ALL, 5)

        self.SetSizer(vbox)
        self.Centre()
        self.Show(True)


class FreqPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        # t = wx.StaticText(self, -1, "This is a Frequency Page object", (20,20))

        # Localize all the panels
        topPanel = SearchConditionPanel(self, -1)
        t = wx.StaticText(self, -1, "This is a Frequency Page object")

        #Set up the panels, align and position them in the right place
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(topPanel, 0, wx.EXPAND | wx.ALL, 5)
        vbox.Add(t, -1, wx.EXPAND | wx.ALL, 5)

        self.SetSizer(vbox)
        self.Centre()
        self.Show(True)

class OrderPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        # Localize all the panels
        self.topPanel = SearchConditionPanel(self, -1)
        self.botPanel = ResultNotebook(self)

        #Set up the panels, align and position them in the right place
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.topPanel, 0, wx.EXPAND | wx.ALL, 5)
        vbox.Add(self.botPanel, -1, wx.EXPAND | wx.ALL, 5)

        self.SetSizer(vbox)
        self.Centre()
        self.Show(True)


class ShopPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        # Creat notebooks for window layout
        shop_notebook = wx.Notebook(self)

        mode_page = ModePage(shop_notebook)
        freq_page = FreqPage(shop_notebook)

        shop_notebook.AddPage(mode_page, u"Mode Analysis")
        shop_notebook.AddPage(freq_page, u"Frequency Analysis")

        # Set up a boxsizer for the tabs
        shop_page_sizer = wx.BoxSizer(wx.HORIZONTAL)
        shop_page_sizer.Add(shop_notebook, 1, wx.EXPAND)
        self.SetSizer(shop_page_sizer)



##**----------------------------------------------------------------------------------**##
##**-------------- Create a windows to display the entire system ---------------------**##    
class OrderAnalysis(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(1024, 576))
        # self.Maximize(True)  # Default display to be maximized

        panel = wx.Panel(self, -1)

        # Creat notebooks for window layout
        main_notebook = wx.Notebook(panel, style=wx.NB_LEFT)

        main_notebook.SetFont(wx.Font(10, wx.FONTFAMILY_DEFAULT,
                         wx.FONTWEIGHT_NORMAL, 
                         wx.FONTSTYLE_NORMAL))

        # create the page windows as children of the notebook
        order_page = OrderPage(main_notebook)
        shop_page = ShopPage(main_notebook)

        # add the pages to the notebook with the label to show on the tab
        main_notebook.AddPage(order_page, u"Order Analysis")
        main_notebook.AddPage(shop_page, u"Shop Analysis")


        # finally, put the notebook in a sizer for the panel to manage
        # the layout
        sizer = wx.BoxSizer()
        sizer.Add(main_notebook, 1, wx.EXPAND)
        panel.SetSizer(sizer)


        self.Centre()
        self.Show(True)


if __name__ == "__main__":
    app = wx.App()
    OrderAnalysis(None, -1, 'Order Info Analyser')
    app.MainLoop()

如您所见,我有一个搜索条件面板和一个在不同页面中使用的结果面板。对于每个特定页面,搜索条件和结果可能不同,仅适用于该页面。所以我的问题是,将搜索条件(即数据和文件名)传递给相应页面以显示结果的最佳方法是什么(即“ResultTablePanel”中的“getResult”函数不起作用)。

例如,在“订单页面”内,搜索条件面板具有用户输入开始和结束日期以及文件名。搜索条件面板下方是结果面板,显示基于搜索条件的计算结果。单击“开始”按钮后,“开始日期”,“结束日期”和“文件名”变量将传递到“订单页面”中的结果面板(“ResultTablePanel”)。同样,由于“模式页面”也同时调用“ResultTablePanel”和“SearchConditionPanel”,它应该有自己的“开始日期”,“结束日期”和“文件名”变量(请注意它们可以与之相同或不同) “订单页面”中的内容,以及“ResultTablePanel”中显示的结果。

提前感谢您抽出时间审核并回答我的问题。

=============================================== =================================

谢谢大家的帮助,我已经想到了使用PubSub和.parent方法的结合。我附上了我的解决方案代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import datetime, time
import wx, sys, wx.grid
import xlrd

import pandas as pd
import numpy as np
import wx.lib.scrolledpanel as scrolled

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

import pandas as pd
import numpy as np

from wx.lib.pubsub import pub 

class ResultTable(wx.grid.PyGridTableBase):
    def __init__(self, data=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.odd=wx.grid.GridCellAttr()
        self.odd.SetBackgroundColour("sky blue")
        self.odd.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
        self.even=wx.grid.GridCellAttr()
        self.even.SetBackgroundColour("sea green")
        self.even.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))

    def GetNumberRows(self):
        if self.data.empty:
            return 5
        else:
            return self.data.shape[0]
    def GetNumberCols(self):
        if self.data.empty:
            return 5
        else:
            return self.data.shape[1]
    def GetValue(self, row, col):
        if self.data.empty:
            return None
        else:
            return self.data.loc[row][col]
    def GetColLabelValue(self, row):
        if self.data.empty:
            return None
        else:
            return list(self.data)[row]
    def SetValue(self, row, col, value):
        pass
    def GetAttr(self, row, col, prop):
        attr = wx.grid.GridCellAttr()
        if row % 2 == 1:
            attr.SetBackgroundColour(EVEN_ROW_COLOUR)
        return attr

    def ResetView(self):
        """Trim/extend the control's rows and update all values"""
        self.getGrid().BeginBatch()
        for current, new, delmsg, addmsg in [
                (self.currentRows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
                (self.currentColumns, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
        ]:
                if new < current:
                        msg = wx.grid.GridTableMessage(
                                self,
                                delmsg,
                                new,    # position
                                current-new,
                        )
                        self.getGrid().ProcessTableMessage(msg)
                elif new > current:
                        msg = wx.grid.GridTableMessage(
                                self,
                                addmsg,
                                new-current
                        )
                        self.getGrid().ProcessTableMessage(msg)
        self.UpdateValues()
        self.getGrid().EndBatch()

        # The scroll bars aren't resized (at least on windows)
        # Jiggling the size of the window rescales the scrollbars
        h,w = grid.GetSize()
        grid.SetSize((h+1, w))
        grid.SetSize((h, w))
        grid.ForceRefresh()

    def UpdateValues( self ):
        """Update all displayed values"""
        msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
        self.getGrid().ProcessTableMessage(msg)

class ResultTablePanel(wx.Panel):
    def __init__(self, parent, id, page):
        wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
        self.grid = wx.grid.Grid(self)

        self.parent = parent

        result = pd.DataFrame({'0' : np.random.randn(100), 'b' : np.random.randn(100), 'c' : np.random.randn(100)})
        result = pd.DataFrame()

        table = ResultTable(result)
        self.grid.SetTable(table)

        self.grid.AutoSize()
        self.grid.AutoSizeColumns(True)
        self.grid.SetGridLineColour(GRID_LINE_COLOUR)

        self.grid.EnableDragGridSize( False )

        self.grid.SetRowLabelSize( 50 )
        self.grid.SetDefaultCellAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )

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

        pub.subscribe(self.getResult, "panelListener")

    def getResult(self, message, page):
        """
        This function should get the variables passed by the analysisOrder function,
        once the button on the SearchConditionPanel is clicked.
        """
        result = pd.DataFrame()

        if page == "Order" and self.parent.GetParent().GetParent().page_identifier == "Order":
            # For test purpose only
            result = pd.DataFrame({'0' : np.random.randn(100), 'b' : np.random.randn(100), 'c' : np.random.randn(100)})  ## For test only

            print "Update Order page"
            table = ResultTable(result)
            self.grid.SetTable(table)
            self.Refresh()
        if page == "Mode" and self.parent.GetParent().GetParent().page_identifier == "Mode":
            result = pd.DataFrame({'0' : np.random.randn(1000), 'b' : np.random.randn(1000)})  ## For test only
            print "Update Mode page"
            table = ResultTable(result)
            self.grid.SetTable(table)
            self.Refresh()
        else:
            pass


class SearchConditionPanel(wx.Panel):
    def __init__(self, parent, id, pageID):
        wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)

        # Creat input box for searching time period
        nameTitleLable = wx.StaticText(self,-1, label=u"File Name:")
        self.fileNameInput = wx.TextCtrl(self,-1, "20170310221612")

        dateTitleLable = wx.StaticText(self,-1, label=u"Date range:")
        yearLable1 = wx.StaticText(self, label=u"Year:")
        monthLable1 = wx.StaticText(self,-1, label=u"Month:")
        dayLable1 = wx.StaticText(self,-1, label=u"Day:")
        yearLable2 = wx.StaticText(self,-1, label=u"Year:")
        monthLable2 = wx.StaticText(self,-1, label=u"Month:")
        dayLable2 = wx.StaticText(self,-1, label=u"Day:")
        startLable = wx.StaticText(self,-1, label=u"Start Date:")
        endLable = wx.StaticText(self,-1, label=u"End Date:")
        self.startYearInput = wx.TextCtrl(self,1, "2016")
        self.startMonthInput = wx.TextCtrl(self,-1, "10")
        self.startDayInput = wx.TextCtrl(self,-1, "30")
        self.endYearInput = wx.TextCtrl(self,-1, "2017")
        self.endMonthInput = wx.TextCtrl(self,-1, "11")
        self.endDayInput = wx.TextCtrl(self,-1, "22")

        self.analysisButton = wx.Button(self, -1, label = u'Start')
        exportButton = wx.Button(self, -1, label = u'Export')
        exportButton.Disable()

        ## Set up overall layout for the panel
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        vbox_File_button = wx.BoxSizer(wx.VERTICAL)
        hbox_file = wx.BoxSizer(wx.HORIZONTAL)
        vbox_date = wx.BoxSizer(wx.VERTICAL)
        hbox_button = wx.BoxSizer(wx.HORIZONTAL)
        hbox_startDate = wx.BoxSizer(wx.HORIZONTAL)
        hbox_endDate = wx.BoxSizer(wx.HORIZONTAL)

        hbox.Add(vbox_date, 0, wx.ALIGN_LEFT | wx.ALL, 5)
        hbox.Add(wx.StaticLine(self, style=wx.LI_VERTICAL), 0, wx.ALL | wx.EXPAND, 5)
        hbox.Add(vbox_File_button, 0, wx.ALIGN_LEFT | wx.ALL, 5)

        ## Setup the layout for the right side
        vbox_File_button.Add(hbox_file, 0, wx.ALIGN_LEFT | wx.ALL, 5)
        vbox_File_button.Add(wx.StaticLine(self), 0, wx.ALL | wx.EXPAND, 5)
        vbox_File_button.Add(hbox_button, 0, wx.ALIGN_LEFT | wx.ALL, 5)

        hbox_file.Add(nameTitleLable, 0, wx.TOP | wx.LEFT | wx.BOTTOM, 10)
        hbox_file.Add(self.fileNameInput, 0, wx.ALL | wx.EXPAND, 5)

        hbox_button.Add(self.analysisButton, 1, wx.TOP | wx.LEFT, 10)
        hbox_button.Add(exportButton, 1, wx.TOP | wx.LEFT, 10)

        ## Setup the layout for the left side
        vbox_date.Add(dateTitleLable, 0, wx.ALL, 5)
        vbox_date.Add(hbox_startDate, 0, wx.ALL | wx.EXPAND, 5)
        vbox_date.Add(hbox_endDate, 0, wx.ALL | wx.EXPAND, 5)

        hbox_startDate.Add(startLable, 0, wx.ALL, 5)
        hbox_startDate.Add(yearLable1, 0, wx.TOP | wx.LEFT | wx.BOTTOM, 5)
        hbox_startDate.Add(self.startYearInput, 0, wx.ALL, 5)
        hbox_startDate.Add(monthLable1, 0, wx.TOP | wx.LEFT | wx.BOTTOM, 5)
        hbox_startDate.Add(self.startMonthInput, 0, wx.ALL|wx.EXPAND, 5)
        hbox_startDate.Add(dayLable1, 0, wx.TOP | wx.LEFT | wx.BOTTOM, 5)
        hbox_startDate.Add(self.startDayInput, 0, wx.ALL|wx.EXPAND, 5)

        hbox_endDate.Add(endLable, 0, wx.LEFT | wx.RIGHT, 5)
        hbox_endDate.Add(yearLable2, 0, wx.LEFT, 5)
        hbox_endDate.Add(self.endYearInput, 0, wx.LEFT | wx.RIGHT, 5)
        hbox_endDate.Add(monthLable2, 0, wx.LEFT, 5)
        hbox_endDate.Add(self.endMonthInput, 0, wx.LEFT | wx.RIGHT, 5)
        hbox_endDate.Add(dayLable2, 0, wx.LEFT, 5)
        hbox_endDate.Add(self.endDayInput, 0, wx.LEFT, 5)

        self.SetSizer(hbox)

        self.Bind(wx.EVT_BUTTON, self.analysisOrder, id=self.analysisButton.GetId())
        self.page_ID = pageID

    def analysisOrder(self,e):
        fileName_temp = self.fileNameInput.GetValue().strip()
        fileName = fileName_temp + '.xls'
        start_date = self.startYearInput.GetValue().strip() + '-' + self.startMonthInput.GetValue().strip() + '-' + self.startDayInput.GetValue().strip()
        end_date = self.endYearInput.GetValue().strip() + '-' + self.endMonthInput.GetValue().strip() + '-' + self.endDayInput.GetValue().strip()

        print "analysis order button called"
        pub.sendMessage("panelListener", message=fileName, page = self.page_ID)

        return fileName, start_date, end_date


class ResultNotebook(wx.Panel):
    def __init__(self, parent, pageID):
        wx.Panel.__init__(self, parent)

        # Creat notebooks for window layout
        result_notebook = wx.Notebook(self)

        self.data_page = ResultTablePanel(result_notebook, -1, page = pageID)

        result_notebook.AddPage(self.data_page, u"Display Data")

        # Set up a boxsizer for the tabs
        result_notebook_sizer = wx.BoxSizer(wx.HORIZONTAL)
        result_notebook_sizer.Add(result_notebook, 1, wx.EXPAND)
        self.SetSizer(result_notebook_sizer)

class ModePage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.page_identifier = "Mode"

        # Localize all the panels
        self.topPanel = SearchConditionPanel(self, -1, pageID = "Mode")
        self.botPanel = ResultNotebook(self, pageID = "Mode")

        #Set up the panels, align and position them in the right place
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.topPanel, 0, wx.EXPAND | wx.ALL, 5)
        vbox.Add(self.botPanel, -1, wx.EXPAND | wx.ALL, 5)

        self.SetSizer(vbox)
        self.Centre()
        self.Show(True)


class FreqPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        # t = wx.StaticText(self, -1, "This is a Frequency Page object", (20,20))

        # Localize all the panels
        topPanel = SearchConditionPanel(self, -1, pageID = "Frequency")
        t = wx.StaticText(self, -1, "This is a Frequency Page object")

        #Set up the panels, align and position them in the right place
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(topPanel, 0, wx.EXPAND | wx.ALL, 5)
        vbox.Add(t, -1, wx.EXPAND | wx.ALL, 5)

        self.SetSizer(vbox)
        self.Centre()
        self.Show(True)

class OrderPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.page_identifier = "Order"

        # Localize all the panels
        self.topPanel = SearchConditionPanel(self, -1, pageID = "Order")
        self.botPanel = ResultNotebook(self, pageID = "Order")

        #Set up the panels, align and position them in the right place
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.topPanel, 0, wx.EXPAND | wx.ALL, 5)
        vbox.Add(self.botPanel, -1, wx.EXPAND | wx.ALL, 5)

        self.SetSizer(vbox)
        self.Centre()
        self.Show(True)


class ShopPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        # Creat notebooks for window layout
        shop_notebook = wx.Notebook(self)

        mode_page = ModePage(shop_notebook)
        freq_page = FreqPage(shop_notebook)

        shop_notebook.AddPage(mode_page, u"Mode Analysis")
        shop_notebook.AddPage(freq_page, u"Frequency Analysis")

        # Set up a boxsizer for the tabs
        shop_page_sizer = wx.BoxSizer(wx.HORIZONTAL)
        shop_page_sizer.Add(shop_notebook, 1, wx.EXPAND)
        self.SetSizer(shop_page_sizer)

##**----------------------------------------------------------------------------------**##
##**-------------- Create a windows to display the entire system ---------------------**##    
class OrderAnalysis(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(1024, 576))
        # self.Maximize(True)  # Default display to be maximized

        panel = wx.Panel(self, -1)

        # Creat notebooks for window layout
        main_notebook = wx.Notebook(panel, style=wx.NB_LEFT)

        main_notebook.SetFont(wx.Font(10, wx.FONTFAMILY_DEFAULT,
                         wx.FONTWEIGHT_NORMAL, 
                         wx.FONTSTYLE_NORMAL))

        # create the page windows as children of the notebook
        order_page = OrderPage(main_notebook)
        shop_page = ShopPage(main_notebook)

        # add the pages to the notebook with the label to show on the tab
        main_notebook.AddPage(order_page, u"Order Analysis")
        main_notebook.AddPage(shop_page, u"Shop Analysis")


        # finally, put the notebook in a sizer for the panel to manage
        # the layout
        sizer = wx.BoxSizer()
        sizer.Add(main_notebook, 1, wx.EXPAND)
        panel.SetSizer(sizer)


        self.Centre()
        self.Show(True)


if __name__ == "__main__":
    app = wx.App()
    OrderAnalysis(None, -1, 'Order Info Analyser')
    app.MainLoop()

再次感谢大家!非常感谢。

2 个答案:

答案 0 :(得分:2)

你提到了三种传递信息的方法,但我必须承认我不明白你在说什么(我已经写了很多wxWidget应用程序)。处理您描述的情况的一种方法是事件处理程序调用父类中的函数,然后父类可以将信息中继到其他函数/类。示意性地:

class A:
    def __init__(self):
        B(self)
        self.c = C(self)

    def a_function(self, *data):
        # do something with the data 
        # you can pass the information to class C here

class B:
    def __init__(self, parent):
        self.parent = parent

    def an_event_handler(self):
        data = something
        self.parent.a_function(data)
        # or use wx.CallAfter for later execution

class C:
    pass

另一个解决方案是MVC概念,其中您的事件处理程序将其信息传递给模型类,模型类存储它或进一步处理它。此模型类可以引发自定义wx事件,然后UI的组件可以根据需要处理以重绘任何受影响的窗口小部件。

答案 1 :(得分:2)

我通常建议使用Pubsub进行此类操作。它非常易于实现,并且可以轻松地将消息传递给一个或多个收件人(面板)。

这是一个简单的例子:

import wx
from wx.lib.pubsub import pub 


class OtherFrame(wx.Frame):
    """"""

    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, wx.ID_ANY, "Secondary Frame")
        panel = wx.Panel(self)

        msg = "Enter a Message to send to the main frame"
        instructions = wx.StaticText(panel, label=msg)
        self.msgTxt = wx.TextCtrl(panel, value="")
        closeBtn = wx.Button(panel, label="Send and Close")
        closeBtn.Bind(wx.EVT_BUTTON, self.onSendAndClose)

        sizer = wx.BoxSizer(wx.VERTICAL)
        flags = wx.ALL|wx.CENTER
        sizer.Add(instructions, 0, flags, 5)
        sizer.Add(self.msgTxt, 0, flags, 5)
        sizer.Add(closeBtn, 0, flags, 5)
        panel.SetSizer(sizer)

    def onSendAndClose(self, event):
        """
        Send a message and close frame
        """
        msg = self.msgTxt.GetValue()
        pub.sendMessage("panelListener", message=msg)
        pub.sendMessage("panelListener", message="test2", arg2="2nd argument!")
        self.Close()


class MyPanel(wx.Panel):
    """"""

    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        pub.subscribe(self.myListener, "panelListener")

        btn = wx.Button(self, label="Open Frame")
        btn.Bind(wx.EVT_BUTTON, self.onOpenFrame)

    def myListener(self, message, arg2=None):
        """
        Listener function
        """
        print "Received the following message: " + message
        if arg2:
            print "Received another arguments: " + str(arg2)

    def onOpenFrame(self, event):
        """
        Opens secondary frame
        """
        frame = OtherFrame()
        frame.Show()


class MyFrame(wx.Frame):
    """"""

    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="PubSub Tutorial")
        panel = MyPanel(self)
        self.Show()


if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

以下是一些其他信息: