2013-11-04 22 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()