Changeset 3478:9c6f3019ac13 in orange


Ignore:
Timestamp:
04/03/07 14:59:28 (7 years ago)
Author:
ales_erjavec <ales.erjavec@…>
Branch:
default
Convert:
c0cb332ad0fe968ed62f17a59917d9d5d0a8eaae
Message:

Data table optimization:

  • custom drawing routine without using the QTableItem (huge memory problem)
  • delayed column adjust for tables with large number of attributes
File:
1 edited

Legend:

Unmodified
Added
Removed
  • orange/OrangeWidgets/Data/OWDataTable.py

    r3420 r3478  
    8181            self.showMetas[id] = (True, []) 
    8282            self.progressBarInit() 
    83             table=QTable(None) 
     83            table=MyTable(None) 
    8484            table.setSelectionMode(QTable.NoSelection) 
    8585            self.id2table[id] = table 
     
    213213            hheader.setLabel(i, var.name) 
    214214        hheader.setLabel(numVarsMetas, "") 
    215  
     215         
    216216        # set the contents of the table (values of attributes) 
    217217        # iterate variables 
     218        table.disableUpdate=True 
     219        table.hide() 
     220        table.ranks={} 
     221        table.values={} 
     222        table.setDelayColumnAdjust(numVarsMetas>200) 
    218223        for j,(key,attr) in enumerate(zip(range(numVars) + metaKeys, varsMetas)): 
     224            #table.setNumCols(j+1) 
     225            #hheader.setLabel(j, attr.name) 
    219226            self.progressBarSet(j*100.0/numVarsMetas) 
    220227            if attr == data.domain.classVar: 
     
    227234            # generate list of tuples (attribute value, instance index) and sort by attrVal 
    228235            valIdx = [(ex[key].native(),idx) for idx,ex in enumerate(data)] 
     236            table.values[j]=[str(v[0])+" " for v in valIdx] 
    229237            valIdx.sort() 
    230238            # generate a dictionary where key: instance index, value: rank 
    231239            idx2rankDict = dict(zip([x[1] for x in valIdx], range(numEx))) 
     240            table.ranks[j]=dict(zip(range(numEx), [x[1] for x in valIdx])) 
     241            table.columnColor[j]=bgColor 
    232242            for i in range(numEx): 
    233243                # set sorting key to ranks 
    234                 OWGUI.tableItem(table, i, j, str(data[i][key]), editType=QTableItem.Never, background=bgColor, sortingKey=self.sortingKey(idx2rankDict[i], numSpaces)) 
     244                pass 
     245                #OWGUI.tableItem(table, i, j, str(data[i][key]), editType=QTableItem.Never, background=bgColor, sortingKey=self.sortingKey(idx2rankDict[i], numSpaces)) 
    235246            # adjust the width of the table 
    236             table.adjustColumn(j) 
    237             table.setColumnWidth(j, table.columnWidth(j)+22) 
    238  
     247            #table.showColumn(j) 
     248            if numVarsMetas<=200: 
     249                table.adjustColumn(j) 
     250            #table.setColumnWidth(j, table.columnWidth(j)+22) 
     251        #for j in range(numVarsMetas): 
     252        #    table.adjustColumn(j) 
    239253        # add hidden column with consecutive numbers for restoring the original order of examples 
    240         for i in range(numEx): 
    241             OWGUI.tableItem(table, i, numVarsMetas, "", editType=QTableItem.Never, sortingKey=self.sortingKey(i, numSpaces)) 
     254        #hheader.setLabel(numVarsMetas, "") 
     255        #table.setNumCols(numVarsMetas+1) 
     256        table.show() 
     257        #for i in range(numEx): 
     258        #    OWGUI.tableItem(table, i, numVarsMetas, "", editType=QTableItem.Never, sortingKey=self.sortingKey(i, numSpaces)) 
     259        table.ranks[table.numCols()-1]=dict([(i,i) for i in range(numEx)]) 
     260        table.values[table.numCols()-1]=["" for i in range(numEx)] 
     261        table.columnColor[table.numCols()-1]=QColor(0,0,0) 
     262        table.disableUpdate=False 
    242263        table.hideColumn(numVarsMetas) 
    243264 
     
    253274        qApp.restoreOverrideCursor() 
    254275        table.setCurrentCell(-1,-1) 
     276        table.clearCache() 
    255277        table.show() 
    256278 
     
    282304# > python OWDataTable.py) 
    283305# Make sure that a sample data set (adult_sample.tab) is in the directory 
    284  
     306from sets import Set 
     307class MyTable(QTable):     
     308    def __init__(self,*args): 
     309        QTable.__init__(self, *args) 
     310        self.disableUpdate=False 
     311        self.disableColumnAdjust=False 
     312        self.adjustedColumnCache=Set() 
     313        self.sortingColumn=-1 
     314        self.sortingAscending=True 
     315        self.delayColumnAdjust=False 
     316        self.columnColor={} 
     317        #self.setWFlags(Qt.WRepaintNoErase | Qt.WNorthWestGravity) 
     318        self.connect(self, SIGNAL("contentsMoving(int, int)"),self.update1) 
     319        self.connect(self.horizontalScrollBar(), SIGNAL("sliderPressed()"), self.sliderPressed) 
     320        self.connect(self.horizontalScrollBar(), SIGNAL("sliderReleased()"), self.sliderReleased) 
     321        self.connect(self, SIGNAL("currentChanged(int, int)"), self.currentSelection) 
     322        self.rectPen=QPen(Qt.black,1) 
     323        self.selectedRectPen=QPen(Qt.black,2) 
     324        self.currentSelected=(-1,-1) 
     325        p=QPainter(self) 
     326        self.setPainterFont(p) 
     327        tm=p.fontMetrics() 
     328        self.charWidth=tm.width("a") 
     329         
     330 
     331    def setDelayColumnAdjust(self, bool): 
     332        self.delayColumnAdjust=bool 
     333         
     334    def clearCache(self): 
     335        self.adjustedColumnCache=Set() 
     336         
     337    def eventFilter(self, obj, event): 
     338        if obj==self or obj==self.horizontalHeader: 
     339            if event.type()==QEvent.Paint and self.delayColumnAdjust: 
     340                self.adjustColumns() 
     341                return True         
     342        return QTable.eventFilter(self, obj, event) 
     343     
     344    def adjustColumns(self): 
     345        if self.disableColumnAdjust: 
     346            return 
     347        #print "adjusting" 
     348        cStart=self.columnAt(self.contentsX())+1 
     349        cEnd=self.columnAt(self.contentsX()+self.visibleWidth()) 
     350        while cStart<min([self.columnAt(self.contentsX()+self.visibleWidth())+1, self.numCols()-1]): 
     351            #for i in range(cStart, cEnd): 
     352            if cStart not in self.adjustedColumnCache: 
     353                self.adjustColumn(cStart) 
     354                #self.setColumnWidth(cStart, self.columnWidth(cStart)+22) 
     355                self.adjustedColumnCache.add(cStart) 
     356            cStart+=1 
     357     
     358    def setColumnWidth(self, i, w): 
     359        #print i 
     360        QTable.setColumnWidth(self, i, w+22) 
     361 
     362    def adjustColumn(self, col): 
     363        p=QPainter(self) 
     364        self.setPainterFont(p) 
     365        tm=p.fontMetrics() 
     366        try: 
     367            maxlen=max([len(t) for t in self.values[col]+[str(self.horizontalHeader().label(col))]]) 
     368            w=self.charWidth*maxlen 
     369            self.setColumnWidth(col,w) 
     370        except KeyError, err: 
     371            pass 
     372            #print "Exception in adjustColumn ", col 
     373                 
     374    def sliderPressed(self): 
     375        self.disableColumnAdjust=True 
     376 
     377    def sliderReleased(self): 
     378        self.disableColumnAdjust=False 
     379        #self.update() 
     380     
     381    def update1(self, i, j): 
     382        self.update() 
     383 
     384    def paintCell(self, painter, row, col, cr, selected): 
     385        #print "Paint cell: ", row, col 
     386        #from pywin import debugger 
     387        #debugger.set_trace() 
     388        if selected: 
     389            painter.setPen(self.selectedRectPen) 
     390            painter.drawRect(cr) 
     391            painter.setPen(self.rectPen) 
     392        else: 
     393            p=QPoint(1,1) 
     394            cr=QRect(cr.topLeft()-p, cr.bottomRight()) 
     395            painter.setPen(self.rectPen) 
     396            painter.drawRect(cr) 
     397        #try: 
     398        if self.sortingAscending: 
     399            text=self.values[col][self.ranks[self.sortingColumn][row]] 
     400        else: 
     401            numAll=self.numRows() 
     402            text=self.values[col][self.ranks[self.sortingColumn][numAll-1-row]] 
     403        painter.drawText(cr, Qt.AlignRight|Qt.AlignVCenter, text) 
     404        #except: 
     405        #    pass 
     406 
     407    def clearCell(self, row, col): 
     408        #print "Clear cell: ", row, col 
     409        p=QPainter(self) 
     410        p.fillRect(self.cellGeometry(row, col), QBrush(Qt.white)) 
     411         
     412    def updateCell(self, row, col): 
     413        #print "Update cell: ",row, col 
     414        if row!=-1 and col!=-1: 
     415            pass 
     416            #self.clearCell(row, col) 
     417        QTable.updateCell(self, row, col) 
     418         
     419    def drawContents(self, painter, cx=0, cy=0, cw=0, ch=0): 
     420        #print "Draw contnents: ",cx,cy,cw,ch 
     421        if self.sortingColumn not in self.ranks: 
     422            self.sortingColumn=self.numCols()-1 
     423        #self.paintEmptyArea(painter, cx, cy, cw, ch) 
     424        self.setPainterFont(painter) 
     425        xStart=self.columnAt(cx) 
     426        xEnd=min([self.columnAt(cx+cw)+1, self.numCols()]) 
     427        yStart=self.rowAt(cy) 
     428        yEnd=min([self.rowAt(cy+ch)+1, self.numRows()]) 
     429        for i in range(xStart, xEnd): 
     430            painter.setBrush(QBrush(self.columnColor[i])) 
     431            for j in range(yStart, yEnd): 
     432                self.paintCell(painter, j, i, self.cellGeometry(j, i), self.isSelected(j, i)) 
     433                 
     434    def paintEvent(self, paintEvent): 
     435        QTable.paintEvent(self, paintEvent) 
     436        painter=QPainter(self) #upper left corner gets painted like the 0,0 cell (why??)  
     437        painter.setBrush(QBrush(Qt.gray)) 
     438        painter.drawRect(1, 1, 32, 20) 
     439 
     440    def paintEmptyArea(self, painter, cx, cy, cw, ch): 
     441        painter.fillRect(cx, cy, cw, ch, QBrush(Qt.white)) 
     442 
     443    def sortColumn(self, col, ascending=True, wholeRows=False): 
     444        self.sortingColumn=col 
     445        self.sortingAscending=ascending 
     446        self.repaintContents(self.contentsX(), self.contentsY(), self.visibleWidth(), self.visibleHeight()) 
     447        #print "sort by: ", col, ascending 
     448 
     449    def currentSelection(self, row, col): 
     450        if self.currentSelected!=(-1,-1): 
     451            r,c=self.currentSelected 
     452            self.currentSelected=(-1,-1) 
     453            self.updateCell(r,c) 
     454        self.currentSelected=(row,col) 
     455        self.updateCell(row,col) 
     456 
     457    def isSelected(self, row, col): 
     458        return self.currentSelected==(row, col) 
     459     
     460    def resizeData(self, i): 
     461        return 
     462 
     463    def setPainterFont(self, painter): 
     464        font=QFont() 
     465        font.setStyleHint(QFont.Courier) 
     466        painter.setFont(font) 
     467 
     468    """     
     469    def columnWidthChanged(self, col): 
     470        pass 
     471        #print col 
     472        #QTable.columnWidthChanged(self, col)""" 
     473         
    285474if __name__=="__main__": 
    286475    a = QApplication(sys.argv) 
Note: See TracChangeset for help on using the changeset viewer.