[wxPython-users] Scrollbar help with DynamicSashWindow

Danny Shevitz shevitz at lanl.gov
Wed Mar 21 14:40:59 PDT 2007


so after a long hiatus, I tried to implement what you said, and I have run 
into another problem
If I put the TreeCtrl inside a panel, I no longer seem to be able to bind 
EVT_DYNAMIC_SASH_SPLIT to
the tree Ctrl.

I have included demo code that shows the problem. In 
MainFrameController::addTreeCtrl, I have a trivial switch. With the switch
set to 1, I add the TreeCtrl directly to the dsw. With the switch set to 0, 
I add the treeCtrl inside a panel.
In the first case, splitting works fine. In the second case, splitting is 
all messed up. I have no idea why.
In both cases, I do the binding directly to the TreeCtrl.

thanks,
Danny

>>I'm using a DSW to present multiple views of a tree. The DSW has it's own 
>>scrollbars.
>>Currently as the length of the tree increases, the TreeCtrl puts up it's 
>>own scrollbars, So I have
>>two scrollbars on the rhs.
>>I know DSW's have scrollbar events as in the demo. What I don't 
>>understand is how
>>to hook up the DSW scrollbars to the TreeCtrl.
>>For the demo, the operative lines are:
>>self.SetVScrollBar(v_bar)
>>self.SetHScrollBar(h_bar)
>>But there are no Set[V|H]ScrollBar methods for a TreeCtrl. For a TreeCtrl 
>>there is
>>a SetScrollbar method, but that just changes the position, not the window.
>>So, I'm stuck. What am I supposed to do?
>
>You could try making the TreeCtrls large enough that they don't need to 
>display their scrollbars, and then respond to the scroll events from the 
>DSW by moving the tree widgets such that the portion that is visible (not 
>clipped by their parent) corresponds to the scrollbar positions.  I think 
>I would approach it by using a custom panel to hold the treectrl and 
>manage sizing it and positioning it.  You can then give it 
>Set[V|H]ScrollBar methods like STC so it can hook itself up to the DSW's 
>scrollbars.
-------------- next part --------------
import wx
import wx.gizmos
from wx.lib.pubsub import Publisher

# Gui Classes -------------------------------------------------------------

class MainFrame(wx.Frame):
	def __init__(self, parent):
		super(MainFrame,self).__init__(parent, wx.ID_ANY, size=(750, 750),pos=(0,0),
						  style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
		self.comboPanel = ComboPanel(self,wx.ID_ANY)
		
class ComboPanel(wx.Panel):
	def __init__(self, *args, **kwargs):
		super(ComboPanel, self).__init__(*args, **kwargs)
		self.splitter=wx.SplitterWindow(self, wx.ID_ANY)
		self.dsw = wx.gizmos.DynamicSashWindow(self.splitter, wx.ID_ANY) #, style=wx.CLIP_CHILDREN, wx.gizmos.DS_MANAGE_SCROLLBARS
		self.rightPanel=RightPanel(self.splitter, wx.ID_ANY)
		self.splitter.SplitVertically(self.dsw, self.rightPanel, -200)
		sizer = wx.BoxSizer(wx.VERTICAL)
		sizer.Add(self.splitter, proportion=1, flag=wx.EXPAND|wx.ALL, border=0)
		self.SetSizerAndFit(sizer)
		self.Layout()
		self.splitter.SetMinimumPaneSize(100)

class MyTree(wx.TreeCtrl):
	def __init__(self, parent):
		super(MyTree, self).__init__(parent, wx.ID_ANY, size=(1000,1000), style=wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS|wx.TR_LINES_AT_ROOT) 
		
class TreePanel(wx.Panel):
	def __init__(self, parent):
		super(TreePanel, self).__init__(parent, wx.ID_ANY)
		self.treeCtrl = MyTree(self)
		sizer = wx.BoxSizer(wx.VERTICAL)
		sizer.Add(self.treeCtrl, proportion=1, flag=wx.EXPAND|wx.ALL, border=0)
		self.SetSizerAndFit(sizer)
		self.Layout()
		
class RightPanel(wx.Panel):
	def __init__(self, *args, **kwargs):
		super(RightPanel, self).__init__(*args, **kwargs)
		bottomlabel = wx.StaticText(self, -1,"Node Properties Editor", (5,5))
		
# Controller Classes -------------------------------------------------------

class MainFrameController(object):
	def __init__(self):
		self.mainFrame = wx.GetApp().mainFrame

	def addTreeCtrl(self):
		if 1:
			newTreeCtrl = MyTree(self.mainFrame.comboPanel.dsw)
		else:
			newTreePanel = TreePanel(self.mainFrame.comboPanel.dsw)
			newTreeCtrl = newTreePanel.treeCtrl
		return newTreeCtrl
		
class MyTreeController(object):	
	def __init__(self, treeCtrl, multiTree):
		self.treeCtrl = treeCtrl
		self.multiTree = multiTree
		self.treeCtrl.AddRoot(self.multiTree.rootText)
		Publisher.subscribe(self.refreshItem, 'view.refreshItem')
		self.treeCtrl.Bind(wx.gizmos.EVT_DYNAMIC_SASH_SPLIT, self.OnSplit)
		self.treeCtrl.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndEdit)
	
	def OnSplit(self, event):
		print "in OnSplit"
		newTreeCtrl = wx.GetApp().mainFrameController.addTreeCtrl()
		MyTreeController(newTreeCtrl, self.multiTree)

	def OnEndEdit(self,event):
		if not event.IsEditCancelled():
			item = event.GetItem()
			wx.CallAfter(self.setNodeText, item) #need to delay name setting f
		
	def setNodeText(self, item):
		label = self.treeCtrl.GetItemText(item)
		self.multiTree.setNodeText(label)

	def refreshItem(self, msg):
		item = self.treeCtrl.GetRootItem()
		self.treeCtrl.SetItemText(item, self.multiTree.rootText)
		
#
# Model Class --------------------------------------------------------------------
#

class AbstractMultiTree(object):
	def __init__(self):
		self.rootText='root text'

	def setNodeText(self, nodeText):
		self.rootText = nodeText.strip()
		Publisher.sendMessage('view.refreshItem')

#
# Model Class --------------------------------------------------------------------
#

class App(wx.App):
	def OnInit(self):
		self.mainFrame = MainFrame(None)
		self.mainFrameController = MainFrameController()
		self.mainFrame.Show(True)
		return True
		

#
# Run the app --------------------------------------------------------------------
#

app = App(0)
newTreeCtrl = app.mainFrameController.addTreeCtrl()
newTree = AbstractMultiTree()
app.mainFrameController.currentController = MyTreeController(treeCtrl=newTreeCtrl, multiTree=newTree)		
app.MainLoop()



More information about the wxpython-users mailing list