Good day,

Hi, I'm trying to develop mapping feature for a tool. It has a wx.ScrolledWindow that contains wx.lib.buttons.GenBitmapTextButton as map nodes. When the number of map nodes reached around 50+ the scrolling becomes too slow. Any ideas on how to improve the performance of the scrolling when there are lots of items inside the wx.ScrolledWindow?

Thanks much!

Recommended Answers

All 3 Replies

A lot depends on how you create your bitmap-button objects.

i have this sub class of GenBitmapTextButton

import wx.lib.buttons as wxButtons
import images
import core
import wx
class mapNode(wxButtons.GenBitmapTextButton):
    def __init__(self, parent, pyData):
        label, name, bitmap, rspFlag, obFlag = self.getProperties(pyData)
        wxButtons.GenBitmapTextButton.__init__(self, parent, id=-1, bitmap=bitmap, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, validator=wx.DefaultValidator, name=name, label=label)
        self.SetFont(wx.Font(pointSize=7, style=90, family=74, weight=90))
        self.pyData = pyData
        self.rspFlag = rspFlag
        self.obFlag = obFlag
    def setPyData(self, pyData):
        self.pyData = pyData
    def DoGetBestSize(self):
        return (80, 30)
    
    def getProperties(self, pyData):
        rspFlag=0
        obFlag=0
        print str(pyData)
        if type(pyData) == core.site:
            label = pyData.database
            name = pyData.database
            bitmap = images.getSiteBitmap()
        elif type(pyData) == core.workflow:
            if pyData.depNo == '-1':
                lblPrefix = '[' +  pyData.creditorNo + '] '
            else:
                lblPrefix = '[' +  pyData.creditorNo + ':' + pyData.depNo + '] '
            label = lblPrefix + pyData.creditorName 
            name = lblPrefix + pyData.creditorName 
            bitmap = images.getWorkflowBitmap() 
        elif type(pyData) == core.category:
            label = pyData.categoryName
            name = pyData.categoryName
            bitmap = images.getFolderCloseBitmap()
        elif type(pyData) == core.tree:
            label = pyData.treeName
            name = pyData.treeName
            bitmap = images.getTreeBitmap()
            if pyData.dctResponseContainer:
                rspFlag = 1
        elif type(pyData) in core.lstActionTypes:
            label = pyData.actionCode
            name = pyData.actionCode
            bitmap = self.getBitmap(pyData)
            if pyData.obCode:
                obFlag=1
            if pyData.dctResponseContainer:
                rspFlag = 1
        elif type(pyData) == core.response:
            label = pyData.responseName
            name = pyData.responseName
            bitmap = images.getResponseBitmap()
            if pyData.obCode:
                obFlag = 1
        return label, name, bitmap, rspFlag, obFlag
    
    def getBitmap(self, acn):
        dctBitmaps = {core.LetterAction: images.getLetterBitmap(), core.PhoneAction: images.getPhoneBitmap(),     core.ManualAction: images.getManualBitmap(),
                    core.GoToAction: images.getGotoBitmap(),       core.JumpToAction: images.getJumptoBitmap(),   core.ReturnToAction: images.getReturntoBitmap(),
                    core.WaitAction: images.getWaitBitmap(),       core.CloseAction: images.getCloseBitmap(),     core.AmendAction: images.getAmendBitmap(), 
                    core.ChangeAction: images.getChangeBitmap(),   core.CostsAction: images.getCostsBitmap(),     core.ErrorAction: images.getErrorBitmap(),
                    core.ExportAction: images.getExportBitmap(),   core.ListAction: images.getListBitmap(),       core.MoveAction: images.getMoveBitmap(),
                    core.NoteAction: images.getNoteBitmap(),       core.UpdateAction: images.getUpdatingBitmap(), core.UnknownAction: images.getFolderBitmap()}
                    
        if dctBitmaps.has_key(type(acn)):
            return dctBitmaps.get(type(acn))
        else:
            return images.getFolderBitmap()

then on other classes i use the method below to populate the map matrix and the map panel (w/c is an instance of wx.ScrolledWindow) with mapNodes

def populateMapMatrix(self, ste):
        self.dctMapMatrix[(0,0)] = mapNode(self.pnlMap, ste)
        self.dctMergedCategories = self.getMergedCategories(ste)
        y = 35
        for wfk, wf in ste.dctWorkflowContainer.items():
            self.dctMapMatrix[(0,y)] = mapNode(self.pnlMap, wf)
            y += 35
        x = 85
        
        for catk, cat in self.dctMergedCategories.items(): 
            self.dctMapMatrix[(x,35)] = mapNode(self.pnlMap, cat)
            for trek, tre in cat.dctTreeContainer.items(): 
                self.dctMapMatrix[(x,70)] = mapNode(self.pnlMap, tre)
                y = 105
                for acn in tre.getSortedActions():
                    self.dctMapMatrix[(x,y)] = mapNode(self.pnlMap, acn)
                    y += 35
                x += 85
    def populatePanelMap(self):
        for pos, node in self.dctMapMatrix.items():
            if node:
                node.SetPosition(pos)
                self.bindNodeEvents(node)
        self.updateNodeToolTipString(None)

sorry for the not so presentable code

found out that ToolTips attached to the nodes are causing the slowdown. removed those and scrolling process is now ok.

def updateNodeToolTipString(self, evt):
        for mxk, mxNode in self.dctMapMatrix.items():
            if mxNode:
                mxNode.SetToolTipString("mx:" + str(mxk) + " mp:" + str(self.pnlMap.CalcUnscrolledPosition(mxNode.GetPositionTuple())))
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.