python - Trying to get a panel on wxPython to change a TextCtrl on another panel -
i in process of writing chat program integrates skype. have of legwork done, having issues notebook control in wxpython. want create new tab on notebook when user sends message, have working, issue have how reference textctrl on panel on tab? following code different project pulled online:
import wx class page(wx.panel): def __init__(self, parent): wx.panel.__init__(self, parent) t = wx.statictext(self, -1, "this page object", (20,20)) class mainframe(wx.frame): def __init__(self): wx.frame.__init__(self, none, title="notebook remove pages example") pannel = wx.panel(self) vbox = wx.boxsizer(wx.vertical) hbox = wx.boxsizer(wx.horizontal) self.buttonremove = wx.button(pannel, id=wx.id_any, label="delete", size=(80, 25)) self.buttonremove.bind(wx.evt_button, self.onbuttonremove) hbox.add(self.buttonremove) self.buttoninsert = wx.button(pannel, id=wx.id_any, label="create", size=(80, 25)) self.buttoninsert.bind(wx.evt_button, self.onbuttoninsert) hbox.add(self.buttoninsert) self.buttonmessage = wx.button(pannel, id=wx.id_any, label="message", size=(80, 25)) self.buttonmessage.bind(wx.evt_button, self.onbuttonmessage) hbox.add(self.buttonlist) vbox.add(hbox) self.notebook3 = wx.notebook(pannel) vbox.add(self.notebook3, 2, flag=wx.expand) pannel.setsizer(vbox) self.pagecounter = 0 self.addpage() def addpage(self): self.pagecounter += 1 page = page(self.notebook3) pagetitle = "page: {0}".format(str(self.pagecounter)) self.notebook3.addpage(page, pagetitle) def onbuttonremove(self, event): page_to_delete = self.notebook3.getselection() self.notebook3.deletepage(page_to_delete) def onbuttoninsert(self, event): self.addpage() def onbuttonmessage(self, event): self.notebook3.statictext(0).appendtext("yeah right. works") if __name__ == "__main__": app = wx.app() mainframe().show() app.mainloop()
i can't seem quite right. appreciated.
yoriz's answer need careful in these situations not violate encapsulation , abstraction.
when comes encapsulation, personal rule-of-thumb of frames/panels/controls/dialogs/etc. allowed call functions 1 level away. is, panel can call functions parent , immediate children. in solution, yoriz calls function 2 levels away; appendtext()
called on page.textctrl
:
def onbuttonmessage(self, event): page = self.notebook3.getcurrentpage() page.textctrl.appendtext("yeah works ")
the problem mainframe
calling functions on objects not have immediate control of. can solved creating wrapper function in page
this:
class page(wx.panel): ... def appendtext(text): self.textctrl.appendtext(text)
and calling in mainframe
this:
class mainframe(wx.frame): def onbuttonmessage(self, event): page = self.notebook3.getcurrentpage() page.appendtext("yeah works ")
this has problem. in order promote code-reuse want our design abstracted possible fewest possible dependencies. mainframe
dependent on notebook3
existing , having textctrl
object (in yoriz's answer) or appendtext()
function (in suggestion above) , create error if isn't case. creates difficulties if attempt reuse mainframe
in different project.
there several ways reduce these types of dependencies personal favourite wxpython's pubsub library (you can find more detailed tutorial here). when button pressed in 1 panel can send out message using pub.sendmessage()
can received other panel can deal appropriately. can include arguments (in case, text set textctrl
to). conceptually similar how wxpython handles button presses, substitute "message" "event".
using pubsub, mainframe
doesn't need know workbook3
. heck, pannel
andworkbook3
can communicate without knowing each other exist; need know messages send/subscribe (i suggest declaring messages constants). makes of components more flexible , reusable.
in code, looks this:
import wx wx.lib.pubsub import setupkwargs #this line not required in wxpython2.9. #see documentation more detail wx.lib.pubsub import pub #this message requires argument "text" msg_change_text = "change.text" class page(wx.panel): def __init__(self, parent): self.textctrl = wx.textctrl(self, -1, "this page object ", style=wx.te_multiline | wx.border_none) ... pub.subscribe(self.onchangetext, msg_change_text) def onchangetext(self, text): self.textctrl.appendtext(text) class mainframe(wx.frame): ... def onbuttonmessage(self, event): pub.sendmessage(msg_change_text, text="yeah works ")
obviously, sample code gave pretty simple in particular case advantages gained using pubsub not worth effort. however, if pannel
, workbook3
didn't share same parent? in case difficult pass instance of workbook3
pannel
, require lot of dependencies on large number of classes. in situations pubsub offers simple, easy, , clean solution.
Comments
Post a Comment