2013-12-10 7 views
2

Я видел вопросы, где вы можете делиться переменными между классами, что я обычно делаю довольно легко. Тем не менее, я пытаюсь использовать переменные между wx.Frame и настраиваемым элементом управления списком. По сути, у меня есть класс с Editable ListCtrl, который использует словарь для сортировки значений в списке. Обычно я просто сделал словарь глобальной переменной, но я пытаюсь полностью удалить глобальные переменные из своего кода. Как я могу ссылаться на словарь в классе ListCtrl класса wx.Frame? ниже - фрагмент кода.wxpython и общие переменные между классами

Спасибо!

class TMainForm(wx.Frame): 
    def __init__(self, *args, **kwds): 
     kwds["style"] = wx.DEFAULT_FRAME_STYLE 
     wx.Frame.__init__(self, *args, **kwds) 

     self.Splitter = wx.SplitterWindow(self, -1) 

     self.Panel1 = wx.Panel(self.Splitter, -1)   
     self.Panel3 = wx.Panel(self.Splitter, -1) 

     self.Splitter.SplitVertically(self.Panel1,self.Panel3,450) 

     self.Notebook2 = wx.Notebook(self.Panel1, -1) 

     # This is the Panel my list is in 
     self.List1 = scrolled.ScrolledPanel(self.Notebook2, -1) 
     self.List1.SetupScrolling() 

     # This custom function creates the dictionary for list 1 (labeled self.List1Data) 
     self.CreateDictionary() 

     # This sets up the listctrl to reference the class EditableListCtrl 
     self.List1_list = EditableListCtrl(self.List1,-1,style=wx.LC_REPORT|wx.LC_SINGLE_SEL) 
     self.List1_list.InsertColumn(1,'Col 1') 
     self.List1_list.InsertColumn(2,'Col 2',format=wx.LIST_FORMAT_CENTRE) 

     items = self.List1Data.items() 
     index = 0 

     for key, data in items: 
      self.List1_list.InsertStringItem(index, data[0]) 
      self.List1_list.SetStringItem(index, 1, data[1]) 
      self.List1_list.SetItemData(index, key) 
      index += 1 

     self.List1_list.itemDataMap = self.List1Data 

     #... 


# In this class i have "List1Data" which is a global variable. I want to grab self.List1Data 
# from the TMainForm class and use it in here (instead of the List1Data global variable). 

class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin, listmix.ColumnSorterMixin): 
    def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, 
       size=wx.DefaultSize, style=0): 
     wx.ListCtrl.__init__(self, parent, ID, pos, size, style) 
     listmix.ColumnSorterMixin.__init__(self, len(List1Data)) 
     self.itemDataMap = List1Data 
    def GetListCtrl(self): 
     return self 

Пытаясь следовать предложенной ответ ниже:

class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin, listmix.ColumnSorterMixin): 

    def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, 
       size=wx.DefaultSize, style=0): 
     wx.ListCtrl.__init__(self, parent, ID, pos, size, style) 
     listmix.ColumnSorterMixin.__init__(self, len(self.List1Data)) 
     self.itemDataMap = self.List1Data 

    def get_dict(self): 
     return self.List1Data 

    def GetListCtrl(self): 
     return self 

* EDIT **

Полный работоспособный код для моего вопроса. См. Комментарий. Я хочу, чтобы иметь возможность ссылаться на self.List1Data в TMainForm в классе EditableListCtrl. Благодаря!

import os 
import wx 
import wx.lib.mixins.listctrl as listmix 
import wx.lib.scrolledpanel as scrolled 

class TMainForm(wx.Frame): 
    def __init__(self, *args, **kwds): 
     kwds["style"] = wx.DEFAULT_FRAME_STYLE 
     wx.Frame.__init__(self, *args, **kwds) 

     self.Splitter = wx.SplitterWindow(self, -1) 

     self.Panel1 = wx.Panel(self.Splitter, -1)   
     self.Panel3 = wx.Panel(self.Splitter, -1) 

     self.Splitter.SplitVertically(self.Panel1,self.Panel3,450) 

     self.Notebook2 = wx.Notebook(self.Panel1, -1) 
     self.List1 = scrolled.ScrolledPanel(self.Notebook2, -1) 
     self.List1.SetupScrolling() 

     self.UpdateData() 

     self.List1_list = EditableListCtrl(self.List1,-1,style=wx.LC_REPORT|wx.LC_SINGLE_SEL) 
     self.List1_list.InsertColumn(1,'Col 1') 
     self.List1_list.InsertColumn(2,'Col 2',format=wx.LIST_FORMAT_CENTRE) 

     self.Update_List() 

     self.List1_list.SetColumnWidth(0,-2) 
     self.List1_list.SetColumnWidth(1,-2) 

     self.Notebook3 = wx.Notebook(self.Panel3, -1) 
     self.OptPane = scrolled.ScrolledPanel(self.Notebook3, -1) 
     self.OptPane.SetupScrolling() 

     self.__set_properties() 
     self.__do_layout() 

    def __set_properties(self): # Set GUI Title and Size 

     self.screen_x = 95 * wx.GetDisplaySize()[0]/100 
     self.screen_y = 90 * wx.GetDisplaySize()[1]/100 

     if wx.GetDisplaySize()[0] < 1920: 
      self.Maximize(True) 
     else: 
      self.SetSize((self.screen_x, self.screen_y)) 
     self.SetMinSize((1280,768)) 

     self.SetFocus() 


    def __do_layout(self , call_fit = True, set_sizer = True): 

     sizer_22 = wx.BoxSizer(wx.VERTICAL) 
     sizer_22.Add(self.List1_list,1,wx.EXPAND) 
     self.List1.SetSizer(sizer_22) 

     self.Notebook2.AddPage(self.List1,"List1") 

     sizer_P2 = wx.BoxSizer(wx.VERTICAL) 
     sizer_P2.Add(self.Notebook2, 1, wx.EXPAND, 0) 
     self.Panel1.SetSizer(sizer_P2) 

     sizer_P3 = wx.BoxSizer(wx.VERTICAL) 
     sizer_P3.Add(self.Notebook3, 1, wx.EXPAND, 0) 
     self.Panel3.SetSizer(sizer_P3) 

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

     self.Layout() 
     self.Centre() 

    def Update_List(self): 

     #items = self.List1Data.items() 
     items = LD1.items() 
     index = 0 

     for key, data in items: 
      self.List1_list.InsertStringItem(index, str(data[0])) 
      self.List1_list.SetStringItem(index, 1, str(data[1])) 

      self.List1_list.SetItemData(index, key) 
      index += 1 

     #self.List1_list.itemDataMap = self.List1Data 
     self.List1_list.itemDataMap = LD1 

    def UpdateData(self): 

     self.List1Data = {} 

     self.List1Data[0] = (1,2,3) 
     self.List1Data[1] = (4,5,6) 

     global LD1 
     LD1 = self.List1Data 

class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin, listmix.ColumnSorterMixin): 

    # I want to be able to get self.List1Data from TMainForm here instead of LD1 
    #print TMainForm.List1Data 

    def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, 
       size=wx.DefaultSize, style=0): 

     wx.ListCtrl.__init__(self, parent, ID, pos, size, style) 
     listmix.ColumnSorterMixin.__init__(self, len(LD1)) 
     self.itemDataMap = LD1 

    def get_dict(self): 
     return self.List1Data 

    def GetListCtrl(self): 
     return self 

app = wx.App(0) 
# Code to Execute File 
class TApplication(wx.App): 
    def OnInit(self): 

      wx.InitAllImageHandlers() 
      MainForm = TMainForm(None, -1,"") 
      self.SetTopWindow(MainForm) 

      MainForm.Show() 
      return 1 

if __name__ == "__main__": 
    Application = TApplication(0) 
    Application.MainLoop() 

Ошибка при попытке получить доступ к List1Data в TMainForm:

Traceback (most recent call last): 
    File "C:/Users/Me/Documents/test.py", line 103, in <module> 
    class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin, listmix.ColumnSorterMixin): 
    File "C:/Users/Me/Documents/test.py", line 106, in EditableListCtrl 
    print TMainForm.List1Data 
AttributeError: type object 'TMainForm' has no attribute 'List1Data' 
+0

Я думаю, что самым простым способом было бы написать функцию геттера/сеттера в подклассе wx.Frame. –

+0

вы можете уточнить? Я никогда не слышал/не видел функцию getter/setter (я думаю) – mcfly

ответ

3
class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin, listmix.ColumnSorterMixin): 

    List1Data={...dictionary item....} 

    def __init__(self): 

    ### your other methods now 

Вы можете получить доступ к List1Data из любого места в других классах только с помощью:

EditableListCtrl.List1Data 

так как теперь, List1Data - это часть определения вашего класса.

+0

Я думаю, что у меня что-то не хватает - я добавил свой код выше, чтобы воспроизвести то, что вы разместили. Я не понимаю, как функция 'get_dict (self)' фактически захватывает 'self.List1Data' из' TMainForm'? Я хочу, чтобы 'self.List1Data' был одинаковым для всех классов (он доступен только для редактирования в классе« TMainForm »). – mcfly

+0

. Пожалуйста, ознакомьтесь с обновленным ответом, и это просто на основе вашего требования. Вы просто должны иметь List1Data как часть определения класса отдельно (не внутри каких-либо методов, просто). Таким образом, вы можете получить к нему доступ, используя только EditableListCtrl.List1Data. –

+0

как поступить другим путем (что я действительно хочу сделать)? Поскольку я определяю List1Data в классе TMainForm, я хочу по существу делать TMainForm.List1Data, но это не позволяет мне это делать (у нас нет атрибута List1Data). Спасибо за помощь, кстати! – mcfly