class FreezeTableWidget(QTableView): def __init__(self, parent=None): QTableView.__init__(self, parent) self.freezeNum = 0 self.inited = False self.frozenTableView = QTableView(self) def columnCountChanged (self, old, new): log('columnCountChanged', old, new) def setSetting(self, setting): if self.inited and setting is not None: if 'freezeNum' in setting: self.setFreezeNum(setting['freezeNum']) if 'hideColumns' in setting: for col in range(self.model().columnCount()): if col in setting['hideColumns']: self.hideColumn(col) else: self.showColumn(col) if 'hideRows' in setting: for row in range(self.model().rowCount()): if row in setting['hideRows']: self.hideRow(row) else: self.showRow(row) def setFreezeNum(self, num): self.resizeColumnsToContents() for col in range(num): self.frozenTableView.setColumnHidden(col, False) if not self.isColumnHidden(col): width = self.columnWidth(col) # log('width:', col, width) if width != 0: self.frozenTableView.setColumnWidth(col, width) # self.setColumnHidden(col, False) for col in range(num, self.model().columnCount()): if not self.frozenTableView.isColumnHidden(col): # self.resizeColumnToContents(col) width = self.frozenTableView.columnWidth(col) self.frozenTableView.setColumnHidden(col, True) if width != 0: self.setColumnWidth(col, width) else: self.frozenTableView.setColumnHidden(col, True) #self.viewport().update() self.freezeNum = num #self.frozenTableView.viewport().stackUnder(self) #self.raise_() #self.viewport().stackUnder(self.frozenTableView); self.updateFrozenTableGeometry() # self.resizeColumnsToContents() def myInit(self, model, freezeNum): self.inited = True self.frozenTableView.setSortingEnabled(True) self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers); self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.setSortingEnabled(True) self.setModel(model) self.setAlternatingRowColors(True) self.freezeNum = freezeNum self.frozenTableView.setModel(self.model()); self.frozenTableView.setFocusPolicy(QtCore.Qt.NoFocus); self.frozenTableView.verticalHeader().hide(); #self.frozenTableView.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed); self.viewport().stackUnder(self.frozenTableView); self.frozenTableView.setStyleSheet("QTableView { border: none;" "background-color: #8EDE21;" "selection-background-color: #999}"); self.frozenTableView.setSelectionModel(self.selectionModel()) self.frozenTableView.setSelectionMode(self.selectionMode()) self.frozenTableView.setSelectionBehavior(self.selectionBehavior()) for col in range(self.freezeNum, self.model().columnCount()): self.frozenTableView.setColumnHidden(col, True) for i in range(self.freezeNum): self.frozenTableView.setColumnWidth(self.freezeNum, self.columnWidth(self.freezeNum) ) self.frozenTableView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff); self.frozenTableView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff); self.frozenTableView.show(); self.setHorizontalScrollMode(self.ScrollPerItem); self.setVerticalScrollMode(self.ScrollPerItem); self.frozenTableView.setVerticalScrollMode(self.ScrollPerItem) self.connect(self.frozenTableView.horizontalHeader(), QtCore.SIGNAL("sortIndicatorChanged (int,Qt::SortOrder)"), self.fSortIndicatorChanged) self.connect(self.horizontalHeader(), QtCore.SIGNAL("sortIndicatorChanged (int,Qt::SortOrder)"), self.sortIndicatorChanged) self.connect(self.horizontalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.updateSectionWidth) self.connect(self.verticalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.updateSectionHeight) self.connect(self.frozenTableView.horizontalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.updateColumn) self.connect(self.frozenTableView.verticalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.updateRow) self.connect(self.frozenTableView.verticalScrollBar(), QtCore.SIGNAL("valueChanged(int)"), self.verticalScrollBar().setValue) self.connect(self.verticalScrollBar(), QtCore.SIGNAL("valueChanged(int)"), self.frozenTableView.verticalScrollBar().setValue) self.resizeColumnsToContents() self.updateFrozenTableGeometry(); def fSortIndicatorChanged(self, index, sortOrder): if index < self.freezeNum: self.frozenTableView.horizontalHeader().setSortIndicatorShown(True) self.horizontalHeader().setSortIndicatorShown(False) def sortIndicatorChanged(self, index, sortOrder): if index >= self.freezeNum: self.frozenTableView.horizontalHeader().setSortIndicatorShown(False) self.horizontalHeader().setSortIndicatorShown(True) def updateColumn(self, logicalIndex, a, newSize): self.setColumnWidth(logicalIndex,newSize); self.updateFrozenTableGeometry() def updateRow(self, logicalIndex, a, newSize): self.setRowHeight(logicalIndex, newSize) def updateSectionWidth(self, logicalIndex, a, newSize): #if logicalIndex==0 or logicalIndex == 1: self.frozenTableView.setColumnWidth(logicalIndex,newSize); self.updateFrozenTableGeometry() def updateSectionHeight(self, logicalIndex, a, newSize): self.frozenTableView.setRowHeight(logicalIndex, newSize); self.updateFrozenTableGeometry() def resizeEvent(self, event): pass QTableView.resizeEvent(self, event); self.updateFrozenTableGeometry() def moveCursor(self, cursorAction, modifiers): pass current = QTableView.moveCursor(self, cursorAction, modifiers); if cursorAction == self.MoveLeft and current.column()>0 \ and self.visualRect(current).topLeft().x() < self.frozenTableView.columnWidth(0): newValue = self.horizontalScrollBar().value() + self.visualRect(current).topLeft().x() - self.frozenTableView.columnWidth(0) self.horizontalScrollBar().setValue(newValue) return current # def scrollTo(self, index, hint): # pass # #if(index.column()>0): # print 'here' #QTableView.scrollTo(self, index, hint) def updateFrozenTableGeometry(self): width = 0 for i in range(self.freezeNum): width += self.columnWidth(i) self.frozenTableView.setGeometry(self.verticalHeader().sizeHint().width()+self.frameWidth(), \ self.frameWidth(), width, self.viewport().height()+self.horizontalHeader().height())
class ListView(QStackedWidget): PAGE_EMPTY = 0 PAGE_LISTVIEW = 1 def __init__(self, parent = None): super(ListView, self).__init__(parent=parent) self.emptyMessage = QLabel("no elements defined yet") self.emptyMessage.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter ) self.emptyMessage.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.addWidget(self.emptyMessage) self._table = QTableView() self.addWidget(self._table) self._table.clicked.connect(self.tableViewCellClicked) self._table.doubleClicked.connect(self.tableViewCellDoubleClicked) self._table.verticalHeader().sectionMoved.connect(self.rowMovedTest) self._table.setShowGrid(False) def resetEmptyMessage(self,pystring): self.emptyMessage.setText(QString(pystring)) def tableViewCellClicked(self, modelIndex): ''' Reimplemt this function to get interaction when double click :param modelIndex: ''' # if (modelIndex.column() == self.model.ColumnID.Delete and # not self._table.model().flags(modelIndex) == Qt.NoItemFlags): # self._table.model().removeRow(modelIndex.row()) # def tableViewCellDoubleClicked(self, modelIndex): ''' Reimplement this function to get interaction when single click :param modelIndex: ''' # if modelIndex.column() == self.model.ColumnID.Color: # self._colorDialog.setBrushColor(self._table.model()[modelIndex.row()].brushColor()) # self._colorDialog.setPmapColor (self._table.model()[modelIndex.row()].pmapColor()) # self._colorDialog.exec_() # #print "brush color = {}".format(self._colorDialog.brushColor().name()) # #print "pmap color = {}".format(self._colorDialog.pmapColor().name()) # self._table.model().setData(modelIndex, (self._colorDialog.brushColor(), # self._colorDialog.pmapColor ())) def rowMovedTest(self, logicalIndex, oldVisualIndex, newVisualIndex): print "{} {} {}".format(logicalIndex, oldVisualIndex, newVisualIndex) def _setListViewLook(self): table = self._table #table.setDragEnabled(True) table.setAcceptDrops(True) table.setFocusPolicy(Qt.NoFocus) table.setShowGrid(False) table.horizontalHeader().hide() table.verticalHeader().hide() #table.horizontalHeader().setResizeMode(1, QHeaderView.Stretch) table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) table.setSelectionMode(QAbstractItemView.SingleSelection) table.setSelectionBehavior(QAbstractItemView.SelectRows) def selectRow(self, *args, **kwargs): self._table.selectRow(*args, **kwargs) def _onRowsChanged(self, parent, start, end): model = self._table.model() if model and model.rowCount() > 0: self.setCurrentIndex(self.PAGE_LISTVIEW) else: self.setCurrentIndex(self.PAGE_EMPTY) if self.parent()!=None: self.parent().updateGeometry() def setModel(self, model): QTableView.setModel(self._table, model) self._table.setSelectionModel(model._selectionModel) if model.rowCount() > 0: self.setCurrentIndex(self.PAGE_LISTVIEW) else: self.setCurrentIndex(self.PAGE_EMPTY) model.rowsInserted.connect(self._onRowsChanged) model.rowsRemoved.connect(self._onRowsChanged) self.model=model self._setListViewLook() @property def allowDelete(self): return not self._table.isColumnHidden(self.model.ColumnID.Delete) @allowDelete.setter def allowDelete(self, allow): self._table.setColumnHidden(self.model.ColumnID.Delete, not allow) def minimumSizeHint(self): #http://www.qtcentre.org/threads/14764-QTableView-sizeHint%28%29-issues t = self._table vHeader = t.verticalHeader() hHeader = t.horizontalHeader() doubleFrame = 2 * t.frameWidth() w = hHeader.length() + vHeader.width() + doubleFrame; contentH = 0 if self._table.model(): for i in range(self._table.model().rowCount()): contentH += self._table.rowHeight(i) contentH = max(90, contentH) h = hHeader.height() + contentH + doubleFrame; from PyQt4.QtCore import QSize return QSize(w,h) def sizeHint(self): return self.minimumSizeHint() def shrinkToMinimum(self): """ shrink the view around the labels which are currently there """ t = self._table hHeader = t.horizontalHeader() doubleFrame = 2 * t.frameWidth() contentH = 0 if self._table.model(): for i in range(self._table.model().rowCount()): contentH += self._table.rowHeight(i) h = contentH+2 self.setFixedHeight(h)
class ListView(QStackedWidget): PAGE_EMPTY = 0 PAGE_LISTVIEW = 1 def __init__(self, parent = None): super(ListView, self).__init__(parent=parent) self.emptyMessage = QLabel("no elements defined yet") self.emptyMessage.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter ) self.emptyMessage.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.addWidget(self.emptyMessage) self._table = QTableView() self.addWidget(self._table) self._table.clicked.connect(self.tableViewCellClicked) self._table.doubleClicked.connect(self.tableViewCellDoubleClicked) self._table.verticalHeader().sectionMoved.connect(self.rowMovedTest) self._table.setShowGrid(False) def resetEmptyMessage(self,pystring): self.emptyMessage.setText(QString(pystring)) def tableViewCellClicked(self, modelIndex): ''' Reimplemt this function to get interaction when double click :param modelIndex: ''' # if (modelIndex.column() == self.model.ColumnID.Delete and # not self._table.model().flags(modelIndex) == Qt.NoItemFlags): # self._table.model().removeRow(modelIndex.row()) # def tableViewCellDoubleClicked(self, modelIndex): ''' Reimplement this function to get interaction when single click :param modelIndex: ''' # if modelIndex.column() == self.model.ColumnID.Color: # self._colorDialog.setBrushColor(self._table.model()[modelIndex.row()].brushColor()) # self._colorDialog.setPmapColor (self._table.model()[modelIndex.row()].pmapColor()) # self._colorDialog.exec_() # #print "brush color = {}".format(self._colorDialog.brushColor().name()) # #print "pmap color = {}".format(self._colorDialog.pmapColor().name()) # self._table.model().setData(modelIndex, (self._colorDialog.brushColor(), # self._colorDialog.pmapColor ())) def rowMovedTest(self, logicalIndex, oldVisualIndex, newVisualIndex): logger.debug( "{} {} {}".format(logicalIndex, oldVisualIndex, newVisualIndex) ) def _setListViewLook(self): table = self._table #table.setDragEnabled(True) table.setAcceptDrops(True) table.setFocusPolicy(Qt.NoFocus) table.setShowGrid(False) table.horizontalHeader().hide() table.verticalHeader().hide() #table.horizontalHeader().setResizeMode(1, QHeaderView.Stretch) table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) table.setSelectionMode(QAbstractItemView.SingleSelection) table.setSelectionBehavior(QAbstractItemView.SelectRows) def selectRow(self, *args, **kwargs): self._table.selectRow(*args, **kwargs) def _onRowsChanged(self, parent, start, end): model = self._table.model() if model and model.rowCount() > 0: self.setCurrentIndex(self.PAGE_LISTVIEW) else: self.setCurrentIndex(self.PAGE_EMPTY) if self.parent()!=None: self.parent().updateGeometry() def setModel(self, model): QTableView.setModel(self._table, model) self._table.setSelectionModel(model._selectionModel) if model.rowCount() > 0: self.setCurrentIndex(self.PAGE_LISTVIEW) else: self.setCurrentIndex(self.PAGE_EMPTY) model.rowsInserted.connect(self._onRowsChanged) model.rowsRemoved.connect(self._onRowsChanged) self.model=model self._setListViewLook() @property def allowDelete(self): return not self._table.isColumnHidden(self.model.ColumnID.Delete) @allowDelete.setter def allowDelete(self, allow): self._table.setColumnHidden(self.model.ColumnID.Delete, not allow) def minimumSizeHint(self): #http://www.qtcentre.org/threads/14764-QTableView-sizeHint%28%29-issues t = self._table vHeader = t.verticalHeader() hHeader = t.horizontalHeader() doubleFrame = 2 * t.frameWidth() w = hHeader.length() + vHeader.width() + doubleFrame; contentH = 0 if self._table.model(): for i in range(self._table.model().rowCount()): contentH += self._table.rowHeight(i) contentH = max(90, contentH) h = hHeader.height() + contentH + doubleFrame; from PyQt4.QtCore import QSize return QSize(w,h) def sizeHint(self): return self.minimumSizeHint() def shrinkToMinimum(self): """ shrink the view around the labels which are currently there """ t = self._table hHeader = t.horizontalHeader() doubleFrame = 2 * t.frameWidth() contentH = 0 if self._table.model(): for i in range(self._table.model().rowCount()): contentH += self._table.rowHeight(i) h = contentH+2 self.setFixedHeight(h)
class FreezeTableWidget(QTableView): def __init__(self, parent=None): QTableView.__init__(self, parent) self.freezeNum = 0 self.inited = False self.frozenTableView = QTableView(self) def columnCountChanged(self, old, new): log('columnCountChanged', old, new) def setSetting(self, setting): if self.inited and setting is not None: if 'freezeNum' in setting: self.setFreezeNum(setting['freezeNum']) if 'hideColumns' in setting: for col in range(self.model().columnCount()): if col in setting['hideColumns']: self.hideColumn(col) else: self.showColumn(col) if 'hideRows' in setting: for row in range(self.model().rowCount()): if row in setting['hideRows']: self.hideRow(row) else: self.showRow(row) def setFreezeNum(self, num): self.resizeColumnsToContents() for col in range(num): self.frozenTableView.setColumnHidden(col, False) if not self.isColumnHidden(col): width = self.columnWidth(col) # log('width:', col, width) if width != 0: self.frozenTableView.setColumnWidth(col, width) # self.setColumnHidden(col, False) for col in range(num, self.model().columnCount()): if not self.frozenTableView.isColumnHidden(col): # self.resizeColumnToContents(col) width = self.frozenTableView.columnWidth(col) self.frozenTableView.setColumnHidden(col, True) if width != 0: self.setColumnWidth(col, width) else: self.frozenTableView.setColumnHidden(col, True) #self.viewport().update() self.freezeNum = num #self.frozenTableView.viewport().stackUnder(self) #self.raise_() #self.viewport().stackUnder(self.frozenTableView); self.updateFrozenTableGeometry() # self.resizeColumnsToContents() def myInit(self, model, freezeNum): self.inited = True self.frozenTableView.setSortingEnabled(True) self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.setSortingEnabled(True) self.setModel(model) self.setAlternatingRowColors(True) self.freezeNum = freezeNum self.frozenTableView.setModel(self.model()) self.frozenTableView.setFocusPolicy(QtCore.Qt.NoFocus) self.frozenTableView.verticalHeader().hide() #self.frozenTableView.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed); self.viewport().stackUnder(self.frozenTableView) self.frozenTableView.setStyleSheet("QTableView { border: none;" "background-color: #8EDE21;" "selection-background-color: #999}") self.frozenTableView.setSelectionModel(self.selectionModel()) self.frozenTableView.setSelectionMode(self.selectionMode()) self.frozenTableView.setSelectionBehavior(self.selectionBehavior()) for col in range(self.freezeNum, self.model().columnCount()): self.frozenTableView.setColumnHidden(col, True) for i in range(self.freezeNum): self.frozenTableView.setColumnWidth( self.freezeNum, self.columnWidth(self.freezeNum)) self.frozenTableView.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.frozenTableView.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.frozenTableView.show() self.setHorizontalScrollMode(self.ScrollPerItem) self.setVerticalScrollMode(self.ScrollPerItem) self.frozenTableView.setVerticalScrollMode(self.ScrollPerItem) self.connect(self.frozenTableView.horizontalHeader(), QtCore.SIGNAL("sortIndicatorChanged (int,Qt::SortOrder)"), self.fSortIndicatorChanged) self.connect(self.horizontalHeader(), QtCore.SIGNAL("sortIndicatorChanged (int,Qt::SortOrder)"), self.sortIndicatorChanged) self.connect(self.horizontalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.updateSectionWidth) self.connect(self.verticalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.updateSectionHeight) self.connect(self.frozenTableView.horizontalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.updateColumn) self.connect(self.frozenTableView.verticalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.updateRow) self.connect(self.frozenTableView.verticalScrollBar(), QtCore.SIGNAL("valueChanged(int)"), self.verticalScrollBar().setValue) self.connect(self.verticalScrollBar(), QtCore.SIGNAL("valueChanged(int)"), self.frozenTableView.verticalScrollBar().setValue) self.resizeColumnsToContents() self.updateFrozenTableGeometry() def fSortIndicatorChanged(self, index, sortOrder): if index < self.freezeNum: self.frozenTableView.horizontalHeader().setSortIndicatorShown(True) self.horizontalHeader().setSortIndicatorShown(False) def sortIndicatorChanged(self, index, sortOrder): if index >= self.freezeNum: self.frozenTableView.horizontalHeader().setSortIndicatorShown( False) self.horizontalHeader().setSortIndicatorShown(True) def updateColumn(self, logicalIndex, a, newSize): self.setColumnWidth(logicalIndex, newSize) self.updateFrozenTableGeometry() def updateRow(self, logicalIndex, a, newSize): self.setRowHeight(logicalIndex, newSize) def updateSectionWidth(self, logicalIndex, a, newSize): #if logicalIndex==0 or logicalIndex == 1: self.frozenTableView.setColumnWidth(logicalIndex, newSize) self.updateFrozenTableGeometry() def updateSectionHeight(self, logicalIndex, a, newSize): self.frozenTableView.setRowHeight(logicalIndex, newSize) self.updateFrozenTableGeometry() def resizeEvent(self, event): pass QTableView.resizeEvent(self, event) self.updateFrozenTableGeometry() def moveCursor(self, cursorAction, modifiers): pass current = QTableView.moveCursor(self, cursorAction, modifiers) if cursorAction == self.MoveLeft and current.column()>0 \ and self.visualRect(current).topLeft().x() < self.frozenTableView.columnWidth(0): newValue = self.horizontalScrollBar().value() + self.visualRect( current).topLeft().x() - self.frozenTableView.columnWidth(0) self.horizontalScrollBar().setValue(newValue) return current # def scrollTo(self, index, hint): # pass # #if(index.column()>0): # print 'here' #QTableView.scrollTo(self, index, hint) def updateFrozenTableGeometry(self): width = 0 for i in range(self.freezeNum): width += self.columnWidth(i) self.frozenTableView.setGeometry(self.verticalHeader().sizeHint().width()+self.frameWidth(), \ self.frameWidth(), width, self.viewport().height()+self.horizontalHeader().height())