def createTable(self, header, tabledata): """creates a table""" gridlayout2 = QGridLayout(self) gridlayout2.setObjectName("gridlayout2") tableView = QTableView(self) tableView.setObjectName("tableView") gridlayout2.addWidget(tableView, 0, 0, 1, 1) self.__popUp = QMenu(tableView) self.__copyAction = QAction(self.tr("Copy data"), tableView) self.connect(self.__copyAction, SIGNAL("triggered()"), self.copy) self.__popUp.addAction(self.__copyAction) tableView.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(tableView, SIGNAL('customContextMenuRequested(QPoint)'), self.popUpMenu) # set the table model tm = TableModel(tabledata, header, self) tableView.setModel(tm) tableView.setAlternatingRowColors(True) # set the minimum size self.setMinimumSize(400, 300) # hide grid tableView.setShowGrid(True) # set the font #font = QFont("Courier New", 12) #self.tableView.setFont(font) # hide vertical header vh = tableView.verticalHeader() vh.setVisible(True) # set horizontal header properties hh = tableView.horizontalHeader() hh.setStretchLastSection(True) # set column width to fit contents tableView.resizeColumnsToContents() tableView.setSortingEnabled(True) tableView.sortByColumn(0, Qt.AscendingOrder) # set row height nrows = len(tabledata) for row in xrange(nrows): tableView.setRowHeight(row, 18)
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
def main(icon_spec): app = QApplication(sys.argv) main_window = QMainWindow() def sigint_handler(*args): main_window.close() signal.signal(signal.SIGINT, sigint_handler) # the timer enables triggering the sigint_handler signal_timer = QTimer() signal_timer.start(100) signal_timer.timeout.connect(lambda: None) tool_bar = QToolBar() main_window.addToolBar(Qt.TopToolBarArea, tool_bar) table_view = QTableView() table_view.setSelectionBehavior(QAbstractItemView.SelectRows) table_view.setSelectionMode(QAbstractItemView.SingleSelection) table_view.setSortingEnabled(True) main_window.setCentralWidget(table_view) proxy_model = QSortFilterProxyModel() proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) proxy_model.setFilterKeyColumn(1) table_view.setModel(proxy_model) proxy_model.layoutChanged.connect(table_view.resizeRowsToContents) item_model = QStandardItemModel() proxy_model.setSourceModel(item_model) # get all icons and their available sizes QIcon.setThemeName("gnome") icons = [] all_sizes = set([]) for context, icon_names in icon_spec: for icon_name in icon_names: icon = QIcon.fromTheme(icon_name) sizes = [] for size in icon.availableSizes(): size = (size.width(), size.height()) sizes.append(size) all_sizes.add(size) sizes.sort() icons.append({ 'context': context, 'icon_name': icon_name, 'icon': icon, 'sizes': sizes, }) all_sizes = list(all_sizes) all_sizes.sort() # input field for filter def filter_changed(value): proxy_model.setFilterRegExp(value) table_view.resizeRowsToContents() filter_line_edit = QLineEdit() filter_line_edit.setMaximumWidth(200) filter_line_edit.setPlaceholderText('Filter name') filter_line_edit.setToolTip('Filter name optionally using regular expressions (' + QKeySequence(QKeySequence.Find).toString() + ')') filter_line_edit.textChanged.connect(filter_changed) tool_bar.addWidget(filter_line_edit) # actions to toggle visibility of available sizes/columns def action_toggled(index): column = 2 + index table_view.setColumnHidden(column, not table_view.isColumnHidden(column)) table_view.resizeColumnsToContents() table_view.resizeRowsToContents() signal_mapper = QSignalMapper() for i, size in enumerate(all_sizes): action = QAction('%dx%d' % size, tool_bar) action.setCheckable(True) action.setChecked(True) tool_bar.addAction(action) action.toggled.connect(signal_mapper.map) signal_mapper.setMapping(action, i) # set tool tip and handle key sequence tool_tip = 'Toggle visibility of column' if i < 10: digit = ('%d' % (i + 1))[-1] tool_tip += ' (%s)' % QKeySequence('Ctrl+%s' % digit).toString() action.setToolTip(tool_tip) signal_mapper.mapped.connect(action_toggled) # label columns header_labels = ['context', 'name'] for width, height in all_sizes: header_labels.append('%dx%d' % (width, height)) item_model.setColumnCount(len(header_labels)) item_model.setHorizontalHeaderLabels(header_labels) # fill rows item_model.setRowCount(len(icons)) for row, icon_data in enumerate(icons): # context item = QStandardItem(icon_data['context']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 0, item) # icon name item = QStandardItem(icon_data['icon_name']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 1, item) for index_in_all_sizes, size in enumerate(all_sizes): column = 2 + index_in_all_sizes if size in icon_data['sizes']: # icon as pixmap to keep specific size item = QStandardItem('') pixmap = icon_data['icon'].pixmap(size[0], size[1]) item.setData(pixmap, Qt.DecorationRole) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) else: # single space to be sortable against icons item = QStandardItem(' ') item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) table_view.resizeColumnsToContents() # manually set row heights because resizeRowsToContents is not working properly for row, icon_data in enumerate(icons): if len(icon_data['sizes']) > 0: max_size = icon_data['sizes'][-1] table_view.setRowHeight(row, max_size[1]) # enable focus find (ctrl+f) and toggle columns (ctrl+NUM) def main_window_keyPressEvent(self, event, old_keyPressEvent=QMainWindow.keyPressEvent): if event.matches(QKeySequence.Find): filter_line_edit.setFocus() return if event.modifiers() == Qt.ControlModifier and event.key() >= Qt.Key_0 and event.key() <= Qt.Key_9: index = event.key() - Qt.Key_1 if event.key() == Qt.Key_0: index += 10 action = signal_mapper.mapping(index) if action: action.toggle() return old_keyPressEvent(self, event) main_window.keyPressEvent = new.instancemethod(main_window_keyPressEvent, table_view, None) # enable copy (ctrl+c) name of icon to clipboard def table_view_keyPressEvent(self, event, old_keyPressEvent=QTableView.keyPressEvent): if event.matches(QKeySequence.Copy): selection_model = self.selectionModel() if selection_model.hasSelection(): index = selection_model.selectedRows()[0] source_index = self.model().mapToSource(index) item = self.model().sourceModel().item(source_index.row(), 1) icon_name = item.data(Qt.EditRole) app.clipboard().setText(icon_name.toString()) return old_keyPressEvent(self, event) table_view.keyPressEvent = new.instancemethod(table_view_keyPressEvent, table_view, None) print 'Icon Theme: ', QIcon.themeName() print 'Theme Search Paths:' for item in QIcon.themeSearchPaths(): print item main_window.showMaximized() return app.exec_()
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())
def main(icon_spec): app = QApplication(sys.argv) main_window = QMainWindow() def sigint_handler(*args): main_window.close() signal.signal(signal.SIGINT, sigint_handler) # the timer enables triggering the sigint_handler signal_timer = QTimer() signal_timer.start(100) signal_timer.timeout.connect(lambda: None) tool_bar = QToolBar() main_window.addToolBar(Qt.TopToolBarArea, tool_bar) table_view = QTableView() table_view.setSelectionBehavior(QAbstractItemView.SelectRows) table_view.setSelectionMode(QAbstractItemView.SingleSelection) table_view.setSortingEnabled(True) main_window.setCentralWidget(table_view) proxy_model = QSortFilterProxyModel() proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) proxy_model.setFilterKeyColumn(1) table_view.setModel(proxy_model) proxy_model.layoutChanged.connect(table_view.resizeRowsToContents) item_model = QStandardItemModel() proxy_model.setSourceModel(item_model) # get all icons and their available sizes QIcon.setThemeName("gnome") icons = [] all_sizes = set([]) for context, icon_names in icon_spec: for icon_name in icon_names: icon = QIcon.fromTheme(icon_name) sizes = [] for size in icon.availableSizes(): size = (size.width(), size.height()) sizes.append(size) all_sizes.add(size) sizes.sort() icons.append({ 'context': context, 'icon_name': icon_name, 'icon': icon, 'sizes': sizes, }) all_sizes = list(all_sizes) all_sizes.sort() # input field for filter def filter_changed(value): proxy_model.setFilterRegExp(value) table_view.resizeRowsToContents() filter_line_edit = QLineEdit() filter_line_edit.setMaximumWidth(200) filter_line_edit.setPlaceholderText('Filter name') filter_line_edit.setToolTip( 'Filter name optionally using regular expressions (' + QKeySequence(QKeySequence.Find).toString() + ')') filter_line_edit.textChanged.connect(filter_changed) tool_bar.addWidget(filter_line_edit) # actions to toggle visibility of available sizes/columns def action_toggled(index): column = 2 + index table_view.setColumnHidden(column, not table_view.isColumnHidden(column)) table_view.resizeColumnsToContents() table_view.resizeRowsToContents() signal_mapper = QSignalMapper() for i, size in enumerate(all_sizes): action = QAction('%dx%d' % size, tool_bar) action.setCheckable(True) action.setChecked(True) tool_bar.addAction(action) action.toggled.connect(signal_mapper.map) signal_mapper.setMapping(action, i) # set tool tip and handle key sequence tool_tip = 'Toggle visibility of column' if i < 10: digit = ('%d' % (i + 1))[-1] tool_tip += ' (%s)' % QKeySequence('Ctrl+%s' % digit).toString() action.setToolTip(tool_tip) signal_mapper.mapped.connect(action_toggled) # label columns header_labels = ['context', 'name'] for width, height in all_sizes: header_labels.append('%dx%d' % (width, height)) item_model.setColumnCount(len(header_labels)) item_model.setHorizontalHeaderLabels(header_labels) # fill rows item_model.setRowCount(len(icons)) for row, icon_data in enumerate(icons): # context item = QStandardItem(icon_data['context']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 0, item) # icon name item = QStandardItem(icon_data['icon_name']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 1, item) for index_in_all_sizes, size in enumerate(all_sizes): column = 2 + index_in_all_sizes if size in icon_data['sizes']: # icon as pixmap to keep specific size item = QStandardItem('') pixmap = icon_data['icon'].pixmap(size[0], size[1]) item.setData(pixmap, Qt.DecorationRole) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) else: # single space to be sortable against icons item = QStandardItem(' ') item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) table_view.resizeColumnsToContents() # manually set row heights because resizeRowsToContents is not working properly for row, icon_data in enumerate(icons): if len(icon_data['sizes']) > 0: max_size = icon_data['sizes'][-1] table_view.setRowHeight(row, max_size[1]) # enable focus find (ctrl+f) and toggle columns (ctrl+NUM) def main_window_keyPressEvent(self, event, old_keyPressEvent=QMainWindow.keyPressEvent): if event.matches(QKeySequence.Find): filter_line_edit.setFocus() return if event.modifiers() == Qt.ControlModifier and event.key( ) >= Qt.Key_0 and event.key() <= Qt.Key_9: index = event.key() - Qt.Key_1 if event.key() == Qt.Key_0: index += 10 action = signal_mapper.mapping(index) if action: action.toggle() return old_keyPressEvent(self, event) main_window.keyPressEvent = new.instancemethod(main_window_keyPressEvent, table_view, None) # enable copy (ctrl+c) name of icon to clipboard def table_view_keyPressEvent(self, event, old_keyPressEvent=QTableView.keyPressEvent): if event.matches(QKeySequence.Copy): selection_model = self.selectionModel() if selection_model.hasSelection(): index = selection_model.selectedRows()[0] source_index = self.model().mapToSource(index) item = self.model().sourceModel().item(source_index.row(), 1) icon_name = item.data(Qt.EditRole) app.clipboard().setText(icon_name.toString()) return old_keyPressEvent(self, event) table_view.keyPressEvent = new.instancemethod(table_view_keyPressEvent, table_view, None) print 'Icon Theme: ', QIcon.themeName() print 'Theme Search Paths:' for item in QIcon.themeSearchPaths(): print item main_window.showMaximized() return app.exec_()
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, 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, 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