class MatlForm(QDialog): def __init__(self): super(MatlForm, self).__init__() if 1 == 0: self.matlModel= QSqlRelationalTableModel(self) self.matlModel.setTable('matl') self.matlModel.setHeaderData(0, Qt.Horizontal,QVariant('name')) self.matlModel.select() self.matlView= QTableView() self.matlView.setModel(self.matlModel) self.matlView.setItemDelegate(MatlDelegate(self)) self.matlView.setSelectionMode(QTableView.SingleSelection) self.matlView.setSelectionBehavior(QTableView.SelectRows) self.matlView.resizeColumnsToContents() self.matlView.layout() matlViewLabel= QLabel("<font color=green size=72><b> Material Editor </b></font>") if 1 == 0: dataLayout= QVBoxLayout() dataLayout.addWidget(self.matlViewLabel) dataLayout.addWidget(self.matlView) self.setLayout(dataLayout) self.matlPopup.show() self.matlPropsHere.show() self.show()
def createTable(self): # create the view tv = QTableView() self.param = self.createParam() # set the delegate to allow editing table entries self.td = SpinBoxDelegate(self.param.traits.xslot) tv.setItemDelegate(self.td) tm = ParamTableModel(self.createParam(), self) tv.setModel(tm) # set the minimum size tv.setMinimumSize(400, 300) # hide grid tv.setShowGrid(False) # set the font font = QFont("Courier New", 8) tv.setFont(font) # hide horizontal header hh = tv.horizontalHeader() hh.setVisible(False) # set vertical header properties vh = tv.verticalHeader() #vh.setStretchLastSection(True) # set column width to fit contents tv.resizeColumnsToContents() return tv
class Window(QWidget): def __init__(self, parent = None): QWidget.__init__(self, parent) self.table = QTableView() self.imageTable = QTableView() delegate = PixelDelegate(self) self.imageTable.setItemDelegate(delegate) self.imageTable.horizontalHeader().hide() self.imageTable.verticalHeader().hide() self.imageTable.setShowGrid(False) self.imageCombo = QComboBox() self.imageCombo.addItem("Dream", QVariant(":/Pictures/dream.png")) self.imageCombo.addItem("Teapot", QVariant(":/Pictures/teapot.png")) gridCheckBox = QCheckBox(self.tr("Show grid:")) gridCheckBox.setCheckState(Qt.Unchecked) self.connect(self.imageCombo, SIGNAL("currentIndexChanged(int)"), self.setModel) self.connect(gridCheckBox, SIGNAL("toggled(bool)"), self.imageTable, SLOT("setShowGrid(bool)")) self.imageCombo.setCurrentIndex(1) layout = QGridLayout() layout.addWidget(self.imageTable, 0, 0, 1, 2) layout.addWidget(self.table, 0, 2, 1, 2) layout.addWidget(gridCheckBox, 1, 0) layout.addWidget(self.imageCombo, 1, 1) self.setLayout(layout) def setModel(self, row): image = QImage(self.imageCombo.itemData(row).toString()) model = ImageModel(image, self) self.table.setModel(model) self.imageTable.setModel(model) for row in range(model.rowCount(QModelIndex())): self.imageTable.resizeRowToContents(row) for column in range(model.columnCount(QModelIndex())): self.imageTable.resizeColumnToContents(column)
class MTestForm(QDialog): def __init__(self, parent=None): super(MTestForm, self).__init__(parent) self.model = SnapshotTableModel() self.model.addSnapshot('test.h5') self.tablev = QTableView() self.tablev.setModel(self.model) self.tablev.setItemDelegate(SnapshotItemDelegate(self)) #for i in range(self.model.columnCount()): self.tablev.resizeColumnsToContents() self.tablev.setColumnHidden(1, True) hb1 = QHBoxLayout() vb2 = QVBoxLayout() vb2.addWidget(ApPlotWidget(), 1.0) vb3a = QVBoxLayout() cb = QCheckBox("show PV") self.connect(cb, SIGNAL("stateChanged(int)"), self._set_pv_view) vb3a.addWidget(cb) vb3a.addStretch() vb3b = QVBoxLayout() vb3b.addWidget(QPushButton("Refresh")) vb3b.addWidget(QPushButton("Plot")) vb3b.addWidget(QPushButton("Ramp")) vb3b.addStretch() hb2 = QHBoxLayout() hb2.addLayout(vb3a, 1.0) hb2.addLayout(vb3b) vb2.addLayout(hb2) hb1.addWidget(self.tablev, .6) hb1.addLayout(vb2, 0.4) self.setLayout(hb1) def _set_pv_view(self, st): if st == Qt.Checked: self.tablev.setColumnHidden(1, False) elif st == Qt.Unchecked: self.tablev.setColumnHidden(1, True)
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 StaffDataDlg(QDialog): def __init__(self, parent=None): super(StaffDataDlg, self).__init__(parent) self.create_widgets() self.layout_widgets() self.create_connections() self.setMinimumWidth(850) self.setWindowTitle(u'Список сотрудников компании') def create_widgets(self): self.model = QtSql.QSqlRelationalTableModel(self) self.model.setTable("employee") self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit) self.model.setRelation(CITY, QtSql.QSqlRelation('cities', 'city_id', 'name')) self.model.setRelation(DEPARTMENT, QtSql.QSqlRelation('deps', 'dep_id', 'name')) self.model.setSort(ID, Qt.AscendingOrder) self.model.setHeaderData(ID, Qt.Horizontal, QVariant("ID")) self.model.setHeaderData(CITY, Qt.Horizontal, QVariant("City")) self.model.setHeaderData(DEPARTMENT, Qt.Horizontal, QVariant("Department")) self.model.setHeaderData(FIRSTNAME, Qt.Horizontal, QVariant("First Name")) self.model.setHeaderData(LASTNAME, Qt.Horizontal, QVariant("Last Name")) self.model.setHeaderData(SEX, Qt.Horizontal, QVariant("sex")) self.model.setHeaderData(ADDRESS, Qt.Horizontal, QVariant("Address")) self.model.setHeaderData(PID, Qt.Horizontal, QVariant("PID")) self.model.setHeaderData(TITLE, Qt.Horizontal, QVariant("Title")) self.model.setHeaderData(SOLARY, Qt.Horizontal, QVariant("SOLARY")) self.model.setHeaderData(SHIFT, Qt.Horizontal, QVariant("SHIFT")) self.model.setHeaderData(HOURS, Qt.Horizontal, QVariant("HOURS")) self.model.select() self.view = QTableView() self.view.setModel(self.model) self.view.setItemDelegate(QtSql.QSqlRelationalDelegate(self)) self.view.setColumnHidden(ID, True) self.view.resizeColumnsToContents() self.buttonBox = QDialogButtonBox() self.addCity = self.buttonBox.addButton(u"&Добавить City", QDialogButtonBox.ActionRole) self.addDep = self.buttonBox.addButton(u"&Добавить Department", QDialogButtonBox.ActionRole) self.addButton = self.buttonBox.addButton(u"&Добавить", QDialogButtonBox.ActionRole) self.deleteButton = self.buttonBox.addButton(u"&Удалить", QDialogButtonBox.ActionRole) self.sortButton = self.buttonBox.addButton(u"&Сортировать", QDialogButtonBox.ActionRole) menu = QMenu(self) self.sortByTitleAction = menu.addAction(u"Сортировка по &Title") self.sortBySolaryAction = menu.addAction( u"Сортировка по &SOLARY") self.sortByIDAction = menu.addAction(u"Сортировка по &ID") self.sortButton.setMenu(menu) self.closeButton = self.buttonBox.addButton(QDialogButtonBox.Close) def layout_widgets(self): layout = QVBoxLayout() layout.addWidget(self.view) layout.addWidget(self.buttonBox) self.setLayout(layout) def create_connections(self): self.addButton.clicked.connect(self.addRecord) self.deleteButton.clicked.connect(self.deleteRecord) self.addCity.clicked.connect(self.editCities) self.sortByTitleAction.triggered.connect( lambda: self.sort(TITLE)) self.sortBySolaryAction.triggered.connect( lambda: self.sort(SOLARY)) self.sortByIDAction.triggered.connect(lambda: self.sort(ID)) self.closeButton.clicked.connect(self.accept) def addRecord(self): row = self.model.rowCount() self.model.insertRow(row) index = self.model.index(row, TITLE) self.view.setCurrentIndex(index) self.view.edit(index) def deleteRecord(self): index = self.view.currentIndex() if not index.isValid(): return record = self.model.record(index.row()) title = record.value(TITLE).toString() desc = record.value(SOLARY).toString() if (QMessageBox.question(self, "Reference Data", QString("Delete %1 from title %2?") .arg(desc).arg(title), QMessageBox.Yes|QMessageBox.No) == QMessageBox.No): return self.model.removeRow(index.row()) self.model.submitAll() def sort(self, column): self.model.setSort(column, Qt.AscendingOrder) self.model.select() def editCities(self): form = ReferenceDataDlg("cities", "Cities", self) form.exec_()
class I4CheckWindow(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setup_model() self.tableview = QTableView() self.tableview.setSelectionMode(QAbstractItemView.NoSelection) self.tableview.setEditTriggers(QAbstractItemView.DoubleClicked) self.cbdelegate = CheckBoxDelegate() self.tableview.setItemDelegate(self.cbdelegate) self.tableview.setAutoScroll(False) self.tableview.setModel(self.model) self.tableview.sortByColumn(0, Qt.AscendingOrder) self.adjust_headers() #self.model.setHeaderData(0, Qt.Horizontal, u"") #self.model.setHeaderData(1, Qt.Horizontal, u"Title") self.radio_all = QRadioButton("All") self.radio_all.setChecked(True) self.radio_need = QRadioButton("Need") self.connect(self.radio_all, SIGNAL("toggled(bool)"), self.set_show_all) label = QLabel("DB:") label.setFixedWidth(40) label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.db_combo = QComboBox() self.populate_db_combo() self.connect( self.db_combo, SIGNAL("currentIndexChanged(int)"), self.db_index_changed) self.new_button = QPushButton("New") self.connect(self.new_button, SIGNAL("clicked()"), self.new_item) self.box = QVBoxLayout(self) self.box.addWidget(self.tableview) self.button_box = QHBoxLayout() self.button_box.setSpacing(0) self.button_box.addWidget(self.new_button) self.button_box.addWidget(self.radio_all) self.button_box.addWidget(self.radio_need) self.button_box.addWidget(label) self.button_box.addWidget(self.db_combo) self.box.addLayout(self.button_box) # self.setStyleSheet(""" # QComboBox { # font-size: 16px; # } # """) self.dwim_after_load() def dwim_after_load(self): if self.model.need_anything(): self.radio_need.setChecked(True) return self.radio_all.setChecked(True) if self.model.model.rowCount() == 0: edit_index = self.model.new() self.tableview.setCurrentIndex(edit_index) self.tableview.scrollTo(edit_index) self.tableview.edit(edit_index) def adjust_headers(self): log.debug("adjust_sizes()") self.tableview.horizontalHeader().setResizeMode(0, QHeaderView.Stretch) self.tableview.setColumnWidth(0, 1) self.tableview.verticalHeader().setDefaultSectionSize(ITEM_HEIGHT) self.tableview.verticalHeader().hide() self.tableview.horizontalHeader().hide() def setup_model(self): self.model = CheckListModel() def new_item(self): index = self.model.new() self.tableview.setCurrentIndex(index) self.tableview.resizeRowToContents(index.row()) self.tableview.scrollTo(index) self.tableview.edit(index) def set_show_all(self, show_all): if self.model.show_all == show_all: return self.model.set_show_all(show_all) self.tableview.resizeRowsToContents() def save(self): self.model.save() def checkout(self): if QMessageBox.question( self, "Checkout", "Are you sure you want to check out?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == \ QMessageBox.Yes: self.model.checkout() def reset_items(self): if QMessageBox.question( self, "Checkout", "Are you sure you want to reset the list?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == \ QMessageBox.Yes: self.model.reset_items() self.radio_all.setChecked(True) def delete_database(self): if QMessageBox.question( self, "Delete database", "Are you sure you want to delete the current database?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == \ QMessageBox.Yes: self.model.delete_database() self.populate_db_combo() self.dwim_after_load() _loading_db_combo = False def populate_db_combo(self): self._loading_db_combo = True try: self.db_combo.clear() for db_name in self.model.databases: self.db_combo.addItem(re.sub("\\.org$", "", db_name), db_name) self.db_combo.addItem("New database...", "") self.db_combo.setCurrentIndex( self.model.databases.index(self.model.current_db)) finally: self._loading_db_combo = False def db_index_changed(self, index): if self._loading_db_combo: return db_name = str(self.db_combo.itemData(index).toPyObject()) if db_name == self.model.current_db: return self.model.save() if db_name: self.model.load(db_name) self.dwim_after_load() return db_name, ok = QInputDialog.getText( self, "New Database", "Enter database name") if ok: if not re.match(r"^[\w-]+$", db_name): QMessageBox.critical( self, "Error", "Database name must contain only the following chars: " "A-Z a-z 0-9 _ -") ok = False elif db_name in self.model.databases: QMessageBox.critical( self, "Error", "Database '%s' already exists" % db_name) ok = False if not ok: self.db_combo.setCurrentIndex( self.model.databases.index(self.model.current_db)) return db_name = str(db_name) + ".org" self.model.load(db_name) self.populate_db_combo() self.dwim_after_load()
class FormItem(QStandardItem): def __init__(self, name, fields, setup): super(FormItem, self).__init__(name) fields = [("Name", str, name)] + fields self.name = lambda: str(self.text()) self.names, _, _ = zip(*fields) self.dtypes = {} self.widgets = {} self.method_names = [] self.val_items = {} self.expr_items = {} self.group_items = {} self.setup = setup self.params_model = QStandardItemModel() self.params_model.itemChanged.connect(self.update_name) self.params_model.setHorizontalHeaderLabels(["Name", "Formula", "Evaluated"]) self.params_widget = QTableView() self.params_widget.setModel(self.params_model) self.params_widget.setItemDelegate(FormDelegate(self.params_model, self.widgets)) self.params_widget.verticalHeader().hide() for name, item_type, default in fields: self.add_field(name, item_type, default) self.params_widget.resizeRowsToContents() self.context_menu = ActionsMenu([]) self.params_model.itemChanged.connect(self.notify_group_item_children) def notify_group_item_children(self, item): method_name = method_style(self.params_model.item(item.row(), 0).text()) if method_name in self.group_items: current_item = self.dtypes[method_name](item.text()) previous_item = self.dtypes[method_name](self.group_items[method_name]) self.group_items[method_name] = current_item current_item.register_dependency(self) previous_item.unregister_dependency(self) def add_field(self, word_name, item_type, value): word_name = word_style(word_name) method_name = method_style(word_name) if item_type is int: self.dtypes[method_name] = int self.widgets[word_name] = lambda: IntVarLineEdit(self.setup) elif item_type is float: self.dtypes[method_name] = float self.widgets[word_name] = lambda: VarLineEdit(self.setup) elif isinstance(item_type, bool): self.dtypes[method_name] = bool self.widgets[word_name] = QCheckBox elif isinstance(item_type, (list, tuple)): self.dtypes[method_name] = str self.widgets[word_name] = \ lambda grp=item_type, **kwargs: MyComboBox(grp, **kwargs) elif isinstance(item_type, GroupItem): group = item_type value = group.items_list()[0].text() self.dtypes[method_name] = lambda i_name, grp=group: grp.item_from_name(i_name) self.widgets[word_name] = \ lambda grp=group, **kwargs: ItemsComboBox(grp, **kwargs) self.group_items[method_name] = value group.item_from_name(value).register_dependency(self) self.expr_items[method_name] = QStandardItem(str(value)) self.val_items[method_name] = ConstantItem("") self.params_model.appendRow([ConstantItem(word_name), self.expr_items[method_name], self.val_items[method_name]]) self.method_names.append(method_name) def set_name(self, name): self.setText(name) self.params_model.item(0, 1).setText(name) def update_name(self): self.setText(self.params_model.item(0, 1).text()) def eval_item(self, item): if item in self.method_names: dtype = self.dtypes[item] text = self.val_items[item].text() if text == "": text = self.expr_items[item].text() return dtype(text) else: raise AttributeError(item) def __getattr__(self, item): return self.eval_item(item)
class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) uic.loadUi("mainwindow.ui", self) model = QStandardItemModel(7, 4, self) for row in range(7): for column in range(4): item = QStandardItem(QString("%1").arg(row * 4 + column)) model.setItem(row, column, item) self.tableView = QTableView() self.tableView.setModel(model) self.setCentralWidget(self.tableView) # 获取视图的项目选择模型 selectionModel = self.tableView.selectionModel() # 定义左上角和右下角的索引,然后使用这两个索引创建选择 topLeft = model.index(1, 1, QModelIndex()) bottomRight = model.index(5, 2, QModelIndex()) selection = QItemSelection(topLeft, bottomRight) # 使用指定的选择模式来选择项目 selectionModel.select(selection, QItemSelectionModel.Select) self.mainToolBar.addAction(_fromUtf8("当前项目"), self.getCurrentItemData) self.mainToolBar.addAction(_fromUtf8("切换选择"), self.toggleSelection) self.connect(selectionModel,SIGNAL("selectionChanged(QItemSelection,QItemSelection)"), self.updateSelection) self.connect(selectionModel, SIGNAL("currentChanged(QModelIndex,QModelIndex)"), self.changeCurrent) # 多个视图共享选择 self.tableView2 = QTableView() self.tableView2.setWindowTitle("tableView2") self.tableView2.resize(400, 300) self.tableView2.setModel(model) self.tableView2.setSelectionModel(selectionModel) self.tableView2.show() # 使用自定义委托 delegate = SpinBoxDelegate(self) self.tableView.setItemDelegate(delegate) # 输出当前项目的内容 def getCurrentItemData(self, ): print "当前项目的内容:", \ self.tableView.selectionModel().currentIndex().data().toString() # 切换选择的项目 def toggleSelection(self): topLeft = self.tableView.model().index(0, 0, QModelIndex()) bottomRight = self.tableView.model().index( self.tableView.model().rowCount(QModelIndex()) - 1, self.tableView.model().columnCount(QModelIndex()) - 1, QModelIndex()) curSelection = QItemSelection(topLeft, bottomRight) self.tableView.selectionModel().select(curSelection, QItemSelectionModel.Toggle) # 更新选择 def updateSelection(self,selected, deselected): mlist = selected.indexes() # 为现在选择的项目填充值 for index in mlist: text = QString("(%1,%2)").arg(index.row()).arg(index.column()) self.tableView.model().setData(index, text) mlist = deselected.indexes() # 清空上一次选择的项目的内容 for index in mlist: self.tableView.model().setData(index, "") # 改变当前项目 def changeCurrent(self, current, previous): print QString("move(%1,%2) to (%3,%4)")\ .arg(previous.row()).arg(previous.column()) \ .arg(current.row()).arg(current.column())
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