visual artifacts in DynamicSashWindow

Howdy,

I am enclosing a code sample that shows a flickering visual artifact when new panes are being added to a DSW.
The enclosed code distills my MVC framework as implemented, ignoring almost everything but the structure.
The flickering problem is caused because I have to do significant initialization before the pane is useful. To
simulate this, I have put a .5 second wait in the TreeCtrl initialization, which in the real code, is where the
wait really is.

Run the code, and split windows at your whim. Notice the split panel blanking out and the small depressed panel artifact in the upper
left hand corner before the newDSW is drawn correctly.

Whenever I run into a problem like this, it is usually a bug of mine. Can anyone help with a way to minimize the artifact?

thanks,
Danny

#%<-------------------------------------------------------------------------------------------------
import wx
import wx.gizmos
import time

class AbstractMultiTree(object):
  pass

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)
    #self.Show(True) # makes no difference whether the show is here or in OnInit
    
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)
    self.rightPanel=RightPanel(self.splitter, wx.ID_ANY)
    self.splitter.SplitVertically(self.dsw, self.rightPanel, -200)
    mainSizer = wx.BoxSizer(wx.VERTICAL)
    mainSizer.Add(self.splitter, proportion=1, flag=wx.EXPAND|wx.ALL, border=0)
    self.SetSizerAndFit(mainSizer)
    self.Layout()
    self.splitter.SetMinimumPaneSize(100)
    
class MyTree(wx.TreeCtrl):
  def __init__(self, parent):
    super(MyTree, self).__init__(parent, wx.ID_ANY, style=wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS|wx.TR_LINES_AT_ROOT|wx.TR_HIDE_ROOT)

flickerArtifact.py (2.26 KB)

···

#
    time.sleep(.5) #simulate a long initialization
    
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))
    
class MainFrameController(object):
  def __init__(self):
    self.mainFrame = wx.GetApp().mainFrame

  def addTreeCtrl(self):
    newTreeCtrl = MyTree(self.mainFrame.comboPanel.dsw)
    newTreeCtrl.AddRoot("hidden display tree root")
    return newTreeCtrl
    
class MyTreeController(object):
  def __init__(self, treeCtrl, multiTree):
    self.treeCtrl = treeCtrl
    self.multiTree = multiTree
    self.treeCtrl.Bind(wx.gizmos.EVT_DYNAMIC_SASH_SPLIT, self.OnSplit)
  
  def OnSplit(self, event):
    newTreeCtrl = wx.GetApp().mainFrameController.addTreeCtrl()
    MyTreeController(newTreeCtrl, self.multiTree)
    
class App(wx.App):
  def OnInit(self):
    self.mainFrame = MainFrame(None)
    self.mainFrameController = MainFrameController()
    self.mainFrame.Show(True)
    return True

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

Danny Shevitz wrote:

Howdy,

I am enclosing a code sample that shows a flickering visual artifact when new panes are being added to a DSW.
The enclosed code distills my MVC framework as implemented, ignoring almost everything but the structure.
The flickering problem is caused because I have to do significant initialization before the pane is useful. To
simulate this, I have put a .5 second wait in the TreeCtrl initialization, which in the real code, is where the
wait really is.

Run the code, and split windows at your whim. Notice the split panel blanking out and the small depressed panel artifact in the upper
left hand corner before the newDSW is drawn correctly.

Whenever I run into a problem like this, it is usually a bug of mine. Can anyone help with a way to minimize the artifact?

Well the obvious fix is to not let the treectrl initialization take so long, at least not at that moment in time when the DSW is in the process of creating new widgets and adjusting layouts. The simplest way to approach this is to just move executing that time-consuming part to the next idle event by using wx.CallAfter. If that still isn't enough then consider moving parts of it to another thread.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!