I was looking for a frozen column example. There is one in official Qt documentation (http://doc.trolltech.com/latest/itemviews-frozencolumn.html), but i needed one using PyQt4. I found one here:
This code was highlighted using http://www.neathighlighter.com/#!python3 #http://python.su/forum/viewtopic.php?id=7346 import sys from PyQt4 import QtGui, QtCore class MyWindow(QtGui.QWidget): def __init__(self, *args): QtGui.QWidget.__init__(self, *args) # create table table = FreezeTableWidget(self) # layout layout = QtGui.QVBoxLayout() layout.addWidget(table) self.setLayout(layout) class FreezeTableWidget(QtGui.QTableView): def __init__(self, parent = None, *args): QtGui.QTableView.__init__(self, parent, *args) # Минимальный размер окна self.setMinimumSize(800, 600) # set the table model tm = MyTableModel(self) # set the proxy model pm = QtGui.QSortFilterProxyModel(self) pm.setSourceModel(tm) # назначаем модель данных для TableView self.setModel(pm) # ***ВИДЖЕТ ЗАФИКСИРОВАННЫХ СТОЛБЦОВ*** # (будет расположен поверх основного) self.frozenTableView = QtGui.QTableView(self) # устанавливаем модель для виджета зафиксированных столбцов self.frozenTableView.setModel(pm) # скрываем заголовки строк self.frozenTableView.verticalHeader().hide() # виджет не принимает фокус self.frozenTableView.setFocusPolicy(QtCore.Qt.NoFocus) # пользователь не может изменять размер столбцов self.frozenTableView.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed) # отключаем показ границ виджета self.frozenTableView.setStyleSheet('''border: none; background-color: #8EDE21; selection-background-color: #999''') # режим выделения как у основного виджета self.frozenTableView.setSelectionModel(QtGui.QAbstractItemView.selectionModel(self)) # убираем полосы прокрутки self.frozenTableView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.frozenTableView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) # помещает дополнительный виджет на передний план self.viewport().stackUnder(self.frozenTableView) # Вход в режим редактирования - еще одним щелчком мыши self.setEditTriggers(QtGui.QAbstractItemView.SelectedClicked) # hide gridnt() # self.setShowGrid(False) # Установка шрифта self.setStyleSheet('font: 10pt "Courier New"') # Установка свойств заголовков столбцов hh = self.horizontalHeader() # выравнивание текста по центру hh.setDefaultAlignment(QtCore.Qt.AlignCenter) # включаем растягивание последнего столбца hh.setStretchLastSection(True) # Установка ширины столбцов по содержимому # self.resizeColumnsToContents() # Установка ширины столбцов ncol = tm.columnCount(self) for col in range(ncol): if col == 0: # устанавливаем размер self.horizontalHeader().resizeSection(col, 60) # фиксируем ширину self.horizontalHeader().setResizeMode(col, QtGui.QHeaderView.Fixed) # ширина фиксированных столбцов - как у основного виджета self.frozenTableView.setColumnWidth(col, self.columnWidth(col)) elif col == 1: self.horizontalHeader().resizeSection(col, 150) self.horizontalHeader().setResizeMode(col, QtGui.QHeaderView.Fixed) self.frozenTableView.setColumnWidth(col, self.columnWidth(col)) else: self.horizontalHeader().resizeSection(col, 100) # скрываем не нужные столбцы у виджета зафиксированных столбцов self.frozenTableView.setColumnHidden(col, True) # Сортировка по щелчку на заголовке столбца self.frozenTableView.setSortingEnabled(True) self.frozenTableView.sortByColumn(0, QtCore.Qt.AscendingOrder) # Включаем чередующуюся подсветку строк self.setAlternatingRowColors(True) # Установка свойств заголовков строк vh = self.verticalHeader() vh.setDefaultSectionSize(25) # высота строк vh.setDefaultAlignment(QtCore.Qt.AlignCenter) # выравнивание текста по центру vh.setVisible(True) # высота строк - как у основного виджета self.frozenTableView.verticalHeader().setDefaultSectionSize(vh.defaultSectionSize()) # Альтернативная устновка высоты строк # nrows = tm.rowCount(self) # for row in xrange(nrows): # self.setRowHeight(row, 25) # показываем наш дополнительный виджет self.frozenTableView.show() # устанавливаем ему размеры как у основного self.updateFrozenTableGeometry() self.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) self.frozenTableView.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel) # Создаем соединения tm.dataChanged.connect(self.test) # connect the headers and scrollbars of both tableviews together self.horizontalHeader().sectionResized.connect(self.updateSectionWidth) self.verticalHeader().sectionResized.connect(self.updateSectionHeight) self.frozenTableView.verticalScrollBar().valueChanged.connect(self.verticalScrollBar().setValue) self.verticalScrollBar().valueChanged.connect(self.frozenTableView.verticalScrollBar().setValue) def test(self, index): print(index.row(), index.column()) def updateSectionWidth(self, logicalIndex, oldSize, newSize): if logicalIndex==0 or logicalIndex==1: self.frozenTableView.setColumnWidth(logicalIndex, newSize) self.updateFrozenTableGeometry() def updateSectionHeight(self, logicalIndex, oldSize, newSize): self.frozenTableView.setRowHeight(logicalIndex, newSize) def resizeEvent(self, event): QtGui.QTableView.resizeEvent(self, event) self.updateFrozenTableGeometry() def scrollTo(self, index, hint): if index.column() > 1: QtGui.QTableView.scrollTo(self, index, hint) def updateFrozenTableGeometry(self): if self.verticalHeader().isVisible(): self.frozenTableView.setGeometry(self.verticalHeader().width() + self.frameWidth(), self.frameWidth(), self.columnWidth(0) + self.columnWidth(1), self.viewport().height() + self.horizontalHeader().height()) else: self.frozenTableView.setGeometry(self.frameWidth(), self.frameWidth(), self.columnWidth(0) + self.columnWidth(1), self.viewport().height() + self.horizontalHeader().height()) # переопределяем функцию moveCursor, для корректного скрола влево с клавиатуры def moveCursor(self, cursorAction, modifiers): current = QtGui.QTableView.moveCursor(self, cursorAction, modifiers) if cursorAction == self.MoveLeft and current.column() > 1 and self.visualRect(current).topLeft().x() < (self.frozenTableView.columnWidth(0) + self.frozenTableView.columnWidth(1)): newValue = self.horizontalScrollBar().value() + self.visualRect(current).topLeft().x() - (self.frozenTableView.columnWidth(0) + self.frozenTableView.columnWidth(1)) self.horizontalScrollBar().setValue(newValue) return current class MyTableModel(QtCore.QAbstractTableModel): def __init__(self, parent = None, *args): QtCore.QAbstractTableModel.__init__(self, parent, *args) self.colLabels = ['Col1', 'Col2', 'Col3', 'Col4', 'Col5', 'Col6', 'Col7', 'Col8', 'Col9', 'Col10'] # Заголовки столбцов self.dataCached = [ [111, 'cell12', 'cell13', 'cell14', 'cell15', 'cell12', 'cell13', 'cell14', 'cell15', 'cell16'], [112, 'cell22', 'cell23', 'cell24', 'cell25', 'cell26', 'cell27', 'cell28', 'cell29', 'cell30'], [113, 'cell32', 'cell33', 'cell34', 'cell35', 'cell36', 'cell37', 'cell38', 'cell39', 'cell40'], [114, 'cell42', 'cell43', 'cell44', 'cell45', 'cell46', 'cell47', 'cell48', 'cell49', 'cell50'], [115, 'cell52', 'cell53', 'cell54', 'cell55', 'cell56', 'cell57', 'cell58', 'cell59', 'cell60'], [116, 'cell62', 'cell63', 'cell64', 'cell65', 'cell66', 'cell67', 'cell68', 'cell69', 'cell70'], [117, 'cell72', 'cell73', 'cell74', 'cell75', 'cell76', 'cell77', 'cell78', 'cell79', 'cell80'], [118, 'cell82', 'cell83', 'cell84', 'cell85', 'cell86', 'cell87', 'cell88', 'cell89', 'cell90'], [119, 'cell12', 'cell13', 'cell14', 'cell15', 'cell12', 'cell13', 'cell14', 'cell15', 'cell16'], [120, 'cell22', 'cell23', 'cell24', 'cell25', 'cell26', 'cell27', 'cell28', 'cell29', 'cell30'], [121, 'cell32', 'cell33', 'cell34', 'cell35', 'cell36', 'cell37', 'cell38', 'cell39', 'cell40'], [122, 'cell42', 'cell43', 'cell44', 'cell45', 'cell46', 'cell47', 'cell48', 'cell49', 'cell50'], [123, 'cell52', 'cell53', 'cell54', 'cell55', 'cell56', 'cell57', 'cell58', 'cell59', 'cell60'], [124, 'cell62', 'cell63', 'cell64', 'cell65', 'cell66', 'cell67', 'cell68', 'cell69', 'cell70'], [125, 'cell72', 'cell73', 'cell74', 'cell75', 'cell76', 'cell77', 'cell78', 'cell79', 'cell80'], [126, 'cell82', 'cell83', 'cell84', 'cell85', 'cell86', 'cell87', 'cell88', 'cell89', 'cell90'], [127, 'cell12', 'cell13', 'cell14', 'cell15', 'cell12', 'cell13', 'cell14', 'cell15', 'cell16'], [128, 'cell22', 'cell23', 'cell24', 'cell25', 'cell26', 'cell27', 'cell28', 'cell29', 'cell30'], [129, 'cell32', 'cell33', 'cell34', 'cell35', 'cell36', 'cell37', 'cell38', 'cell39', 'cell40'], [130, 'cell42', 'cell43', 'cell44', 'cell45', 'cell46', 'cell47', 'cell48', 'cell49', 'cell50'], [131, 'cell52', 'cell53', 'cell54', 'cell55', 'cell56', 'cell57', 'cell58', 'cell59', 'cell60'], [132, 'cell62', 'cell63', 'cell64', 'cell65', 'cell66', 'cell67', 'cell68', 'cell69', 'cell70'], [133, 'cell72', 'cell73', 'cell74', 'cell75', 'cell76', 'cell77', 'cell78', 'cell79', 'cell80'], [134, 'cell82', 'cell83', 'cell84', 'cell85', 'cell86', 'cell87', 'cell88', 'cell89', 'cell90'], [135, 'cell82', 'cell83', 'cell84', 'cell85', 'cell86', 'cell87', 'cell88', 'cell89', 'cell90'], [136, 'cell82', 'cell83', 'cell84', 'cell85', 'cell86', 'cell87', 'cell88', 'cell89', 'cell90'] ] # Область данных # Возвращает количество строк def rowCount(self, parent): return len(self.dataCached) # Возвращает количество столбцов def columnCount(self, parent): return len(self.colLabels) # Возвращает значение ячейки def get_value(self, index): i = index.row() j = index.column() return self.dataCached[i][j] # Значение и свойства ячейки данных в зависимости от роли def data(self, index, role): if not index.isValid(): return None value = self.get_value(index) if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole: return value elif role == QtCore.Qt.TextAlignmentRole: return QtCore.Qt.AlignCenter return None # Изменение значения ячейки def setData(self, index, value, role): if index.isValid() and role == QtCore.Qt.EditRole: self.dataCached[index.row()][index.column()] = value self.dataChanged.emit(index, index) return True else: return False # Заголовки столбцов и строк def headerData(self, section, orientation, role): #заголовки столбцов if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: header = self.colLabels[section] return header #заголовки строк if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole: return str(section + 1) return None # Переопределяем метод flags (включаем выделение и редактирование в ячейках) def flags(self, index): if not index.isValid(): return QtCore.Qt.ItemIsEnabled elif index.column() > 1: return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable if __name__ == "__main__": app = QtGui.QApplication(sys.argv) w = MyWindow() w.show() sys.exit(app.exec())
No comments:
Post a Comment