class FreezeTableWidget(QTableView): def __init__(self, table_data, headers, parent=None, *args): """ Creates two QTableViews one of which is a frozen table while the other one can scroll behind it. :param table_data: The data that goes into the tables :type table_data: List :param headers: The header data of the tables. :type headers: List :param parent: The parent of the QTableView :type parent: QWidget :param args: :type args: """ QTableView.__init__(self, parent) # set the table model self.table_model = BaseSTDMTableModel(table_data, headers, parent) # set the proxy model proxy_model = QSortFilterProxyModel(self) proxy_model.setSourceModel(self.table_model) # Assign a data model for TableView self.setModel(self.table_model) # frozen_table_view - first column self.frozen_table_view = QTableView(self) # Set the model for the widget, fixed column self.frozen_table_view.setModel(self.table_model) # Hide row headers self.frozen_table_view.verticalHeader().hide() # Widget does not accept focus self.frozen_table_view.setFocusPolicy(Qt.StrongFocus | Qt.TabFocus | Qt.ClickFocus) # The user can not resize columns self.frozen_table_view.horizontalHeader().\ setResizeMode(QHeaderView.Fixed) self.frozen_table_view.setObjectName('frozen_table') self.setSelectionMode(QAbstractItemView.NoSelection) self.set_style() # Remove the scroll bar self.frozen_table_view.setHorizontalScrollBarPolicy( Qt.ScrollBarAlwaysOff) self.frozen_table_view.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff) # Puts more widgets to the foreground self.viewport().stackUnder(self.frozen_table_view) # # Log in to edit mode - even with one click # Set the properties of the column headings hh = self.horizontalHeader() # Text alignment centered hh.setDefaultAlignment(Qt.AlignCenter) self.set_column_width() # Set properties header lines vh = self.verticalHeader() vh.setDefaultSectionSize(25) # height lines # text alignment centered vh.setDefaultAlignment(Qt.AlignCenter) vh.setVisible(True) # Height of rows - as in the main widget self.frozen_table_view.verticalHeader().\ setDefaultSectionSize( vh.defaultSectionSize() ) # Show frozen table view self.frozen_table_view.show() # Set the size of him like the main self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.frozen_table_view.setVerticalScrollMode( QAbstractItemView.ScrollPerPixel) ## select the first column (STR Type) self.frozen_table_view.selectColumn(0) self.frozen_table_view.setEditTriggers( QAbstractItemView.AllEditTriggers) self.set_size() self.signals() def set_size(self): """ Sets the size and size policy of the tables. :return: :rtype: """ size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(size_policy) self.setMinimumSize(QSize(55, 75)) self.setMaximumSize(QSize(5550, 5555)) self.SelectionMode(QAbstractItemView.SelectColumns) # set column width to fit contents self.frozen_table_view.resizeColumnsToContents() # set row height self.frozen_table_view.resizeRowsToContents() def signals(self): """ Connects signals of the tables. """ # Connect the headers and scrollbars of # both tableviews together self.horizontalHeader().sectionResized.connect( self.update_section_width) self.verticalHeader().sectionResized.connect( self.update_section_height) self.frozen_table_view.verticalScrollBar(). \ valueChanged.connect( self.verticalScrollBar().setValue ) self.verticalScrollBar().valueChanged.connect( self.frozen_table_view.verticalScrollBar().setValue) def set_column_width(self): """ Sets the column width of the frozen QTableView. """ # Set the width of columns columns_count = self.table_model.columnCount(self) for col in range(columns_count): if col == 0: # Set the size self.horizontalHeader().resizeSection(col, 60) # Fix width self.horizontalHeader().setResizeMode(col, QHeaderView.Fixed) # Width of a fixed column - as in the main widget self.frozen_table_view.setColumnWidth(col, self.columnWidth(col)) elif col == 1: self.horizontalHeader().resizeSection(col, 150) self.horizontalHeader().setResizeMode(col, QHeaderView.Fixed) self.frozen_table_view.setColumnWidth(col, self.columnWidth(col)) else: self.horizontalHeader().resizeSection(col, 150) # Hide unnecessary columns in the # widget fixed columns self.frozen_table_view.setColumnHidden(col, True) def set_style(self): """ Sets the style of the frozen table. """ # Style frozentable view self.frozen_table_view.setStyleSheet(''' #frozen_table{ border-top:none; } ''') self.shadow = QGraphicsDropShadowEffect(self) self.shadow.setBlurRadius(5) self.shadow.setOffset(2) self.shadow.setYOffset(0) self.frozen_table_view.setGraphicsEffect(self.shadow) def add_widgets(self, str_type_id, insert_row): """ Adds widget delete into the frozen table. :param str_type_id: The STR type id of the tenure type combobox :type str_type_id: Integer :param insert_row: The row number the widgets to be added. :type insert_row: Integer """ delegate = STRTypeDelegate(str_type_id) # Set delegate to add combobox under # social tenure type column self.frozen_table_view.setItemDelegate(delegate) self.frozen_table_view.setItemDelegateForColumn(0, delegate) index = self.frozen_table_view.model().index(insert_row, 0, QModelIndex()) self.frozen_table_view.model().setData(index, '', Qt.EditRole) self.frozen_table_view.openPersistentEditor( self.frozen_table_view.model().index(insert_row, 0)) self.frozen_table_view.openPersistentEditor( self.frozen_table_view.model().index(insert_row, 1)) def update_section_width(self, logicalIndex, oldSize, newSize): """ Updates frozen table column width and geometry. :param logicalIndex: The section's logical number :type logicalIndex: Integer :param oldSize: The old size of the section :type oldSize: Integer :param newSize: The new size of the section :type newSize: Integer """ if logicalIndex == 0 or logicalIndex == 1: self.frozen_table_view.setColumnWidth(logicalIndex, newSize) self.update_frozen_table_geometry() def update_section_height(self, logicalIndex, oldSize, newSize): """ Updates frozen table column height. :param logicalIndex: The section's logical number :type logicalIndex: Integer :param oldSize: The old size of the section :type oldSize: Integer :param newSize: The new size of the section :type newSize: Integer """ self.frozen_table_view.setRowHeight(logicalIndex, newSize) def resizeEvent(self, event): """ Handles the resize event of the frozen table view. It updates the frozen table view geometry on resize of table. :param event: The event :type event: QEvent """ QTableView.resizeEvent(self, event) try: self.update_frozen_table_geometry() except Exception as log: LOGGER.debug(str(log)) def scrollTo(self, index, hint): """ Scrolls the view if necessary to ensure that the item at index is visible. The view will try to position the item according to the given hint. :param index: The scroll index :type index: QModelIndex :param hint: The scroll hint :type hint: Integer """ if index.column() > 1: QTableView.scrollTo(self, index, hint) def update_frozen_table_geometry(self): """ Updates the frozen table view geometry. """ if self.verticalHeader().isVisible(): self.frozen_table_view.setGeometry( self.verticalHeader().width() + self.frameWidth(), self.frameWidth(), self.columnWidth(0) + self.columnWidth(1), self.viewport().height() + self.horizontalHeader().height()) else: self.frozen_table_view.setGeometry( self.frameWidth(), self.frameWidth(), self.columnWidth(0) + self.columnWidth(1), self.viewport().height() + self.horizontalHeader().height()) def move_cursor(self, cursor_action, modifiers): """ Override function for correct left to scroll the keyboard. Returns a QModelIndex object pointing to the next object in the table view, based on the given cursorAction and keyboard modifiers specified by modifiers. :param cursor_action: The cursor action :type cursor_action: Integer :param modifiers: Qt.KeyboardModifier value. :type modifiers: Object :return: The current cursor position. :rtype: QModelIndex """ current = QTableView.move_cursor(self, cursor_action, modifiers) if cursor_action == self.MoveLeft and current.column() > 1 and \ self.visualRect(current).topLeft().x() < \ (self.frozen_table_view.columnWidth(0) + self.frozen_table_view.columnWidth(1)): new_value = self.horizontalScrollBar().value() + \ self.visualRect(current).topLeft().x() - \ (self.frozen_table_view.columnWidth(0) + self.frozen_table_view.columnWidth(1)) self.horizontalScrollBar().setValue(new_value) return current
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 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 FreezeTableWidget(QTableView): def __init__(self, parent=None): QTableView.__init__(self, parent) self.freezeNum = 0 def myInit(self, model, freezeNum): self.setModel(model) self.frozenTableView = QTableView(self) self.frozenTableView.setSortingEnabled(True) self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.setSortingEnabled(True) self.setAlternatingRowColors(True) self.freezeNum = freezeNum self.init() 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.a) self.connect(self.frozenTableView.verticalHeader(), QtCore.SIGNAL("sectionResized(int,int,int)"), self.b) self.connect(self.frozenTableView.verticalScrollBar(), QtCore.SIGNAL("valueChanged(int)"), self.verticalScrollBar().setValue) self.connect(self.verticalScrollBar(), QtCore.SIGNAL("valueChanged(int)"), self.frozenTableView.verticalScrollBar().setValue) 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 init(self): 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.updateFrozenTableGeometry(); self.setHorizontalScrollMode(self.ScrollPerPixel); self.setVerticalScrollMode(self.ScrollPerPixel); self.frozenTableView.setVerticalScrollMode(self.ScrollPerPixel) def a(self, logicalIndex, a, newSize): self.setColumnWidth(logicalIndex,newSize); self.updateFrozenTableGeometry() def b(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); 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().width()+self.frameWidth(), \ self.frameWidth(), width, self.viewport().height()+self.horizontalHeader().height())
class FreezeTableWidget(QTableView): def __init__( self, table_data, headers, parent = None, *args ): """ Creates two QTableViews one of which is a frozen table while the other one can scroll behind it. :param table_data: The data that goes into the tables :type table_data: List :param headers: The header data of the tables. :type headers: List :param parent: The parent of the QTableView :type parent: QWidget :param args: :type args: """ QTableView.__init__(self, parent) # set the table model self.table_model = BaseSTDMTableModel( table_data, headers, parent ) # set the proxy model proxy_model = QSortFilterProxyModel(self) proxy_model.setSourceModel(self.table_model) # Assign a data model for TableView self.setModel(self.table_model) # frozen_table_view - first column self.frozen_table_view = QTableView(self) # Set the model for the widget, fixed column self.frozen_table_view.setModel(self.table_model) # Hide row headers self.frozen_table_view.verticalHeader().hide() # Widget does not accept focus self.frozen_table_view.setFocusPolicy( Qt.StrongFocus|Qt.TabFocus|Qt.ClickFocus ) # The user can not resize columns self.frozen_table_view.horizontalHeader().\ setResizeMode(QHeaderView.Fixed) self.frozen_table_view.setObjectName('frozen_table') self.setSelectionMode(QAbstractItemView.NoSelection) # Remove the scroll bar self.frozen_table_view.setHorizontalScrollBarPolicy( Qt.ScrollBarAlwaysOff ) self.frozen_table_view.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff ) # Puts more widgets to the foreground self.viewport().stackUnder(self.frozen_table_view) # # Log in to edit mode - even with one click # Set the properties of the column headings hh = self.horizontalHeader() # Text alignment centered hh.setDefaultAlignment(Qt.AlignCenter) self.set_column_width() # Set properties header lines vh = self.verticalHeader() vh.setDefaultSectionSize(25) # height lines # text alignment centered vh.setDefaultAlignment(Qt.AlignCenter) vh.setVisible(True) # Height of rows - as in the main widget self.frozen_table_view.verticalHeader().\ setDefaultSectionSize( vh.defaultSectionSize() ) # Show frozen table view self.frozen_table_view.show() # Set the size of him like the main self.setHorizontalScrollMode( QAbstractItemView.ScrollPerPixel ) self.setVerticalScrollMode( QAbstractItemView.ScrollPerPixel ) self.frozen_table_view.setVerticalScrollMode( QAbstractItemView.ScrollPerPixel ) ## select the first column (STR Type) self.frozen_table_view.selectColumn(0) self.frozen_table_view.setEditTriggers( QAbstractItemView.AllEditTriggers ) self.set_size() self.signals() def set_size(self): """ Sets the size and size policy of the tables. :return: :rtype: """ size_policy = QSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed ) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth( self.sizePolicy().hasHeightForWidth() ) self.setSizePolicy(size_policy) self.setMinimumSize(QSize(55, 75)) self.setMaximumSize(QSize(5550, 5555)) self.SelectionMode( QAbstractItemView.SelectColumns ) # set column width to fit contents self.frozen_table_view.resizeColumnsToContents() # set row height self.frozen_table_view.resizeRowsToContents() def signals(self): """ Connects signals of the tables. """ # Connect the headers and scrollbars of # both tableviews together self.horizontalHeader().sectionResized.connect( self.update_section_width ) self.verticalHeader().sectionResized.connect( self.update_section_height ) self.frozen_table_view.verticalScrollBar().valueChanged.connect( self.verticalScrollBar().setValue ) self.verticalScrollBar().valueChanged.connect( self.frozen_table_view.verticalScrollBar().setValue ) def set_column_width(self): """ Sets the column width of the frozen QTableView. """ # Set the width of columns columns_count = self.table_model.columnCount(self) for col in range(columns_count): if col == 0: # Set the size self.horizontalHeader().resizeSection( col, 60 ) # Fix width self.horizontalHeader().setResizeMode( col, QHeaderView.Fixed ) # Width of a fixed column - as in the main widget self.frozen_table_view.setColumnWidth( col, self.columnWidth(col) ) elif col == 1: self.horizontalHeader().resizeSection( col, 150 ) self.horizontalHeader().setResizeMode( col, QHeaderView.Fixed ) self.frozen_table_view.setColumnWidth( col, self.columnWidth(col) ) else: self.horizontalHeader().resizeSection( col, 150 ) # Hide unnecessary columns in the # widget fixed columns self.frozen_table_view.setColumnHidden( col, True ) def add_widgets(self, spatial_unit, insert_row): """ Adds widget into the frozen table. :param str_type_id: The STR type id of the tenure type combobox :type str_type_id: Integer :param insert_row: The row number the widgets to be added. :type insert_row: Integer """ delegate = STRTypeDelegate(spatial_unit) # Set delegate to add combobox under # social tenure type column self.frozen_table_view.setItemDelegate( delegate ) self.frozen_table_view.setItemDelegateForColumn( 0, delegate ) index = self.frozen_table_view.model().index( insert_row, 0, QModelIndex() ) self.frozen_table_view.model().setData( index, '', Qt.EditRole ) self.frozen_table_view.openPersistentEditor( self.frozen_table_view.model().index(insert_row, 0) ) self.frozen_table_view.openPersistentEditor( self.frozen_table_view.model().index(insert_row, 1) ) def update_section_width( self, logicalIndex, oldSize, newSize ): """ Updates frozen table column width and geometry. :param logicalIndex: The section's logical number :type logicalIndex: Integer :param oldSize: The old size of the section :type oldSize: Integer :param newSize: The new size of the section :type newSize: Integer """ if logicalIndex==0 or logicalIndex==1: self.frozen_table_view.setColumnWidth( logicalIndex, newSize ) self.update_frozen_table_geometry() def update_section_height( self, logicalIndex, oldSize, newSize ): """ Updates frozen table column height. :param logicalIndex: The section's logical number :type logicalIndex: Integer :param oldSize: The old size of the section :type oldSize: Integer :param newSize: The new size of the section :type newSize: Integer """ self.frozen_table_view.setRowHeight( logicalIndex, newSize ) def resizeEvent(self, event): """ Handles the resize event of the frozen table view. It updates the frozen table view geometry on resize of table. :param event: The event :type event: QEvent """ QTableView.resizeEvent(self, event) try: self.update_frozen_table_geometry() except Exception as log: LOGGER.debug(str(log)) def scrollTo(self, index, hint): """ Scrolls the view if necessary to ensure that the item at index is visible. The view will try to position the item according to the given hint. :param index: The scroll index :type index: QModelIndex :param hint: The scroll hint :type hint: Integer """ if index.column() > 1: QTableView.scrollTo(self, index, hint) def update_frozen_table_geometry(self): """ Updates the frozen table view geometry. """ if self.verticalHeader().isVisible(): self.frozen_table_view.setGeometry( self.verticalHeader().width() + self.frameWidth(), self.frameWidth(), self.columnWidth(0) + self.columnWidth(1), self.viewport().height() + self.horizontalHeader().height() ) else: self.frozen_table_view.setGeometry( self.frameWidth(), self.frameWidth(), self.columnWidth(0) + self.columnWidth(1), self.viewport().height() + self.horizontalHeader().height() ) def move_cursor(self, cursor_action, modifiers): """ Override function for correct left to scroll the keyboard. Returns a QModelIndex object pointing to the next object in the table view, based on the given cursorAction and keyboard modifiers specified by modifiers. :param cursor_action: The cursor action :type cursor_action: Integer :param modifiers: Qt.KeyboardModifier value. :type modifiers: Object :return: The current cursor position. :rtype: QModelIndex """ current = QTableView.move_cursor( self, cursor_action, modifiers ) if cursor_action == self.MoveLeft and current.column() > 1 and \ self.visualRect(current).topLeft().x() < \ (self.frozen_table_view.columnWidth(0) + self.frozen_table_view.columnWidth(1)): new_value = self.horizontalScrollBar().value() + \ self.visualRect(current).topLeft().x() - \ (self.frozen_table_view.columnWidth(0) + self.frozen_table_view.columnWidth(1)) self.horizontalScrollBar().setValue(new_value) return current