2013-11-04 52 views
1

我有一個問題.. wxPython listctrl在筆記本上在筆記本上使用listctrl wxPython

我創建了2個tab使用筆記本。

我在第一個選項卡中添加了按鈕,並在第二個選項卡中添加了Listctrl。

如果我點擊按鈕,將Listctrl中的值添加到第二個選項卡。 如何解決這個問題?

import wx 

class PageOne(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.query_find_btn = wx.Button(self, 4, "BTN", (40,40)) 
     self.Bind(wx.EVT_BUTTON, self.AddList, id = 4) 

    def AddList(self, evt): 
     self.list1.InsertStringItem(0,'Hello') 

class PageTwo(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.list1 = wx.ListCtrl(self,-1,wx.Point(0,0),wx.Size(400,400),style=wx.LC_REPORT | wx.SUNKEN_BORDER) 
     self.list1.InsertColumn(0,'values') 

class MyFrame(wx.Frame): 
    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self,parent,id,title,size=(400,400),pos=wx.Point(100,100), 
     style=wx.SYSTEM_MENU |wx.CAPTION) 

     p = wx.Panel(self) 
     nb = wx.Notebook(p) 

     MainFrame = PageOne(nb) 
     SecondFrame = PageTwo(nb) 

     nb.AddPage(MainFrame, "One") 
     nb.AddPage(SecondFrame, "Two") 

     sizer = wx.BoxSizer() 
     sizer.Add(nb, 1, wx.EXPAND) 
     p.SetSizer(sizer) 


class MyApp(wx.App): 
    def OnInit(self): 
     self.frame=MyFrame(None,-1,'Unknown.py') 
     self.frame.Centre() 
     self.frame.Show() 
     return True 

if __name__ == '__main__': 
    app = MyApp(False) 
    app.MainLoop() 
+1

顯示您的代碼。將listctrl重新記爲類屬性,如'self.mylistctrl',以便在所有類中都可以訪問它。 – furas

+0

@furas感謝您的回覆!我添加了代碼 –

+0

@furas真的非常感謝兄弟!!!!!!!!!!!! T^T –

回答

0

我用GetParent()得到MyFrame,比我能得到SecondFrame

def AddList(self, evt): 
    # PageOne -> Notebook -> Panel -> MyFrame (3x GetParent()) 
    self.GetParent().GetParent().GetParent().SecondFrame.list1.InsertStringItem(0,'Hello') 

MyFrame我要補充self.所有SecondFrame(不一定MainFrame

也許它可以事件綁定完成,但我不知道。

全碼:

import wx 

class PageOne(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.query_find_btn = wx.Button(self, 4, "BTN", (40,40)) 
     self.Bind(wx.EVT_BUTTON, self.AddList, id = 4) 

    def AddList(self, evt): 
     # PageOne -> Notebook -> Panel -> MyFrame (3x GetParent()) 
     self.GetParent().GetParent().GetParent().SecondFrame.list1.InsertStringItem(0,'Hello') 


class PageTwo(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.list1 = wx.ListCtrl(self,-1,wx.Point(0,0),wx.Size(400,400),style=wx.LC_REPORT | wx.SUNKEN_BORDER) 
     self.list1.InsertColumn(0,'values') 

class MyFrame(wx.Frame): 
    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self,parent,id,title,size=(400,400),pos=wx.Point(100,100), 
     style=wx.SYSTEM_MENU |wx.CAPTION) 

     p = wx.Panel(self) 
     nb = wx.Notebook(p) 

     # add self. 
     self.MainFrame = PageOne(nb) 
     self.SecondFrame = PageTwo(nb) 

     # add self. 
     nb.AddPage(self.MainFrame, "One") 
     nb.AddPage(self.SecondFrame, "Two") 

     sizer = wx.BoxSizer() 
     sizer.Add(nb, 1, wx.EXPAND) 
     p.SetSizer(sizer) 


class MyApp(wx.App): 
    def OnInit(self): 
     self.frame=MyFrame(None,-1,'Unknown.py') 
     self.frame.Centre() 
     self.frame.Show() 
     return True 

if __name__ == '__main__': 
    app = MyApp(False) 
    app.MainLoop() 
+0

您應該使用self.GetTopLevelParent()而不是一系列GetParent()調用。這種做法也非常脆弱。如果程序員更改小部件的名稱,則會中斷。我建議使用pubsub或類似的東西在類之間進行交流。 –

+0

我在寫''時可能會聽到類似於聽衆的東西',但我不知道'':)。與聽衆,它是非常容易和彈性。 – furas

0

我在重複的問題回答了這一點,但這裏要再次重申的完整性:

有一對夫婦的方式來處理這一點。你可以這樣做的愚蠢的方式,像這樣:

import wx 

class PageOne(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.query_find_btn = wx.Button(self, -1, "BTN", (40,40)) 
     self.Bind(wx.EVT_BUTTON, self.AddList, self.query_find_btn) 

    def AddList(self, evt): 
     frame = self.GetTopLevelParent() 
     frame.pageTwo.list1.InsertStringItem(0,'Hello') 

class PageTwo(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.list1 = wx.ListCtrl(self,-1,wx.Point(0,0),wx.Size(400,400),style=wx.LC_REPORT | wx.SUNKEN_BORDER) 
     self.list1.InsertColumn(0,'values') 

class MyFrame(wx.Frame): 
    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self,parent,id,title,size=(400,400),pos=wx.Point(100,100), 
     style=wx.SYSTEM_MENU |wx.CAPTION) 

     p = wx.Panel(self) 
     nb = wx.Notebook(p) 

     self.pageOne = PageOne(nb) 
     self.pageTwo = PageTwo(nb) 

     nb.AddPage(self.pageOne, "One") 
     nb.AddPage(self.pageTwo, "Two") 

     sizer = wx.BoxSizer() 
     sizer.Add(nb, 1, wx.EXPAND) 
     p.SetSizer(sizer) 


class MyApp(wx.App): 
    def OnInit(self): 
     self.frame=MyFrame(None,-1,'Unknown.py') 
     self.frame.Centre() 
     self.frame.Show() 
     return True 

if __name__ == '__main__': 
    app = MyApp(False) 
    app.MainLoop() 

或者您可以使用發佈訂閱,這是更清潔,更容易破裂。這裏有一種方法:

import wx 
from wx.lib.pubsub import pub 

class PageOne(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.query_find_btn = wx.Button(self, -1, "BTN", (40,40)) 
     self.Bind(wx.EVT_BUTTON, self.AddList, self.query_find_btn) 

    def AddList(self, evt): 
     pub.sendMessage("listctrlListener", message="Hello") 

class PageTwo(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.list1 = wx.ListCtrl(self,-1,wx.Point(0,0),wx.Size(400,400),style=wx.LC_REPORT | wx.SUNKEN_BORDER) 
     self.list1.InsertColumn(0,'values') 
     pub.subscribe(self.updateListCtrl, "listctrlListener") 

    #---------------------------------------------------------------------- 
    def updateListCtrl(self, message): 
     """""" 
     self.list1.InsertStringItem(0, message) 

class MyFrame(wx.Frame): 
    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self,parent,id,title,size=(400,400),pos=wx.Point(100,100), 
     style=wx.SYSTEM_MENU |wx.CAPTION) 

     p = wx.Panel(self) 
     nb = wx.Notebook(p) 

     MainFrame = PageOne(nb) 
     SecondFrame = PageTwo(nb) 

     nb.AddPage(MainFrame, "One") 
     nb.AddPage(SecondFrame, "Two") 

     sizer = wx.BoxSizer() 
     sizer.Add(nb, 1, wx.EXPAND) 
     p.SetSizer(sizer) 


class MyApp(wx.App): 
    def OnInit(self): 
     self.frame=MyFrame(None,-1,'Unknown.py') 
     self.frame.Centre() 
     self.frame.Show() 
     return True 

if __name__ == '__main__': 
    app = MyApp(False) 
    app.MainLoop() 

這是使用pubsub的新API。你可以在這裏看到使用它的另一個例子:

  • ​​

如果你碰巧使用舊版本的wxPython的(預2.8.10),那麼你可能需要使用發佈訂閱的舊的API,你可以讀到這裏:

另外請注意,I R emoved按鈕的ID。您不應該將按鈕的ID設置爲較低的數字,因爲它可能會在wxPython內部使用。建議如果你要創建一個id,你應該這樣做是這樣的:

btnId = wx.NewId() 
+0

感謝兄弟! 代碼很簡單!令人驚歎的XD。 wxPython對我來說很難T^T 無論如何這個代碼效率比@ furas的代碼更好。 非常感謝Mike Driscoll和furas! –

0

另一種方法是使用父的孩子之間進行調解,並創建面板上的接口的方法來保持通話短並保護內部的變化。

import wx 


class PageOne(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.query_find_btn = wx.Button(self, label="BTN", size=(40, 40)) 

    def bind_find_btn(self, handler): 
     self.query_find_btn.Bind(wx.EVT_BUTTON, handler) 


class PageTwo(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.list1 = wx.ListCtrl(self, pos=(0, 0), size=(400, 400), 
      style=wx.LC_REPORT | wx.SUNKEN_BORDER) 
     self.list1.InsertColumn(0, 'values') 

    def insert_list_item(self, text): 
     self.list1.InsertStringItem(0, text) 


class MyFrame(wx.Frame): 
    def __init__(self, parent, title): 
     wx.Frame.__init__(self, parent, title=title, size=(400, 400), 
      pos=(100, 100), style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX) 

     p = wx.Panel(self) 
     nb = wx.Notebook(p) 

     self.mainframe = PageOne(nb) 
     self.secondframe = PageTwo(nb) 

     nb.AddPage(self.mainframe, "One") 
     nb.AddPage(self.secondframe, "Two") 

     sizer = wx.BoxSizer() 
     sizer.Add(nb, 1, wx.EXPAND) 
     p.SetSizer(sizer) 
     sizer.Layout() 

     self.mainframe.bind_find_btn(self.on_button) 

    def on_button(self, event): 
     self.secondframe.insert_list_item('Hello') 


class MyApp(wx.App): 
    def OnInit(self): 
     self.frame = MyFrame(None, 'Unknown.py') 
     self.frame.Centre() 
     self.frame.Show() 
     return True 

if __name__ == '__main__': 
    app = MyApp(False) 
    app.MainLoop()