def __openTable(self): self.qryModel = QSqlQueryModel(self) self.qryModel.setQuery( '''SELECT empNo, Name, Gender, Birthday, Province, Department, Salary FROM employee ORDER BY empNo''' ) if self.qryModel.lastError().isValid(): QMessageBox.critical( self, "错误", "数据表查询错误,错误信息\n" + self.qryModel.lastError().text()) return self.__getFieldNames() self.qryModel.setHeaderData(0, Qt.Horizontal, "工号") self.qryModel.setHeaderData(1, Qt.Horizontal, "姓名") self.qryModel.setHeaderData(2, Qt.Horizontal, "性别") self.qryModel.setHeaderData(3, Qt.Horizontal, "出生日期") self.qryModel.setHeaderData(4, Qt.Horizontal, "省份") self.qryModel.setHeaderData(5, Qt.Horizontal, "部门") self.qryModel.setHeaderData(6, Qt.Horizontal, "工资") self.selModel = QItemSelectionModel(self.qryModel) self.selModel.currentRowChanged.connect(self.do_currentRowChanged) self.ui.tableView.setModel(self.qryModel) self.ui.tableView.setSelectionModel(self.selModel) self.ui.actOpenDB.setEnabled(False) self.ui.actRecInsert.setEnabled(True) self.ui.actRecDelete.setEnabled(True) self.ui.actRecEdit.setEnabled(True) self.ui.actScan.setEnabled(True) self.ui.actTestSQL.setEnabled(True)
def __init__(self, treeManipulate, tabnumber): self.treeManipulate = treeManipulate self.tabnumber = tabnumber self.tvattributesview = None self.lenameattributes = None self.levalueattributes = None self.battributesinsert = None self.battributesdelete = None self.battributeshelp = None self.setUiInit() self.helptext = self.treeManipulate.main.attribhelp #build empty model for data and the selection self.attribmodel = AttribStandardItemModel(self.tvattributesview) self.attribmodel.setHorizontalHeaderLabels(["Name", "Value", "var/fun", "comment"]) self.attribselectionmodel = QItemSelectionModel(self.attribmodel) #set model to tableview self.tvattributesview.setModel(self.attribmodel) self.tvattributesview.setSelectionModel(self.attribselectionmodel) #signals self.battributesinsert.clicked.connect(self.addAttrib) self.battributesdelete.clicked.connect(self.deleteAttrib) self.battributeshelp.clicked.connect(self.help) self.attribmodel.itemChanged.connect(self.changeAttrib) #resize self.resz() #variables self.changeOnce = True #prevent the changeAttrib() function from being executed twice (the second time by the model change)
def _biaocaozuo(self): self.model = QtSql.QSqlTableModel() self.model.setTable('BookData') self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) # 设置保存策略 self.table_view.setModel(self.model) self.model.select() self.model.setHeaderData(0, Qt.Horizontal, 'ISBN') self.model.setHeaderData(1, Qt.Horizontal, '书名') self.model.setHeaderData(2, Qt.Horizontal, '作者') self.model.setHeaderData(3, Qt.Horizontal, '出版社') self.model.setHeaderData(4, Qt.Horizontal, '出版日期') self.model.setHeaderData(5, Qt.Horizontal, '评分') self.model.setHeaderData(6, Qt.Horizontal, '照片') self.table_view.setColumnHidden(6, True) self.mapper = QDataWidgetMapper() self.mapper.setModel(self.model) self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit) self.mapper.addMapping(self.lineEdit_ISBN, 0) self.mapper.addMapping(self.lineEdit_shuming, 1) self.mapper.addMapping(self.lineEdit_zuozhe, 2) self.mapper.addMapping(self.lineEdit_chubanshe, 3) self.mapper.addMapping(self.lineEdit_chubanriqi, 4) self.mapper.addMapping(self.lineEdit_pingfen, 5) self.mapper.toFirst() self.selModel = QItemSelectionModel(self.model) # 选择模型 self.table_view.setSelectionModel(self.selModel) self.selModel.currentChanged.connect( self.do_currentChanged) # 当前项变化时触发 self.selModel.currentRowChanged.connect( self.do_currentRowChanged) # 选择行变化时
def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.__dlgSetHeaders = None self.setCentralWidget(self.ui.tableView) ##构建状态栏 self.LabCellPos = QLabel("当前单元格:", self) self.LabCellPos.setMinimumWidth(180) self.ui.statusBar.addWidget(self.LabCellPos) self.LabCellText = QLabel("单元格内容:", self) self.LabCellText.setMinimumWidth(200) self.ui.statusBar.addWidget(self.LabCellText) ##构建Item Model/View self.itemModel = QStandardItemModel(10, 5, self) #数据模型,10行5列 self.selectionModel = QItemSelectionModel(self.itemModel) #Item选择模型 self.selectionModel.currentChanged.connect(self.do_currentChanged) ##为tableView设置数据模型 self.ui.tableView.setModel(self.itemModel) #设置数据模型 self.ui.tableView.setSelectionModel(self.selectionModel) #设置选择模型
def __init__(self, parent=None): QTreeView.__init__(self, parent) #model self._model = CategoriesTreeModel(self) self.setModel(self._model) # selectionMode self._selection_model = QItemSelectionModel(self._model, self) self.setSelectionModel(self._selection_model) #delegate self._delegate = CategoriesTreeDelegate(parent) self.setItemDelegate(self._delegate) #阻止双击时出现编辑框 self.setEditTriggers(self.NoEditTriggers) #设置展开/收缩动画 self.setAnimated(True) #展开所有 self.expandAll() #开启右键自定义菜单 self.setContextMenuPolicy(Qt.CustomContextMenu) #右键菜单信号槽 self.customContextMenuRequested.connect(self._slot_custom_context_menu) #右键菜单项 self._context_menu_add_child = QAction('添加子分类') self._context_menu_add_child.triggered.connect( self._slot_context_menu_add_child) self._context_menu_rename = QAction('重命名') self._context_menu_rename.triggered.connect( self._slot_context_menu_rename) self._context_menu_delete = QAction('删除该分类') self._context_menu_delete.triggered.connect( self._slot_context_menu_delete) # 设置默认选择为 root self._selection_model.select(self.rootIndex(), QItemSelectionModel.SelectCurrent)
def set_model_common(self, model, list_base_class) -> None: if self.selection_model: self.selection_model.selectionChanged.disconnect() list_base_class.setModel(self, model) self.selection_model = QItemSelectionModel(model) self.selection_model.selectionChanged.connect(self._selection_changed) self.setSelectionModel(self.selection_model)
def __init__(self, parent, main): QDialog.__init__(self, parent) self.ui = Ui_IMDBSearchDialog() self.ui.setupUi(self) self._main = main self.ui.searchMovieButton.clicked.connect(self.onSearchMovieButton) self.ui.movieInfoButton.clicked.connect(self.onMovieInfoButton) self.ui.okButton.clicked.connect(self.onOkButton) self.ui.cancelButton.clicked.connect(self.onCancelButton) header = self.ui.searchResultsView.horizontalHeader() header.setSectionResizeMode(QHeaderView.Stretch) header.hide() self.ui.searchResultsView.verticalHeader().hide() self.imdbModel = ImdbListModel(self) self.ui.searchResultsView.setModel(self.imdbModel) # FIXME: This connection should be cleaner. self.imdbModel._main = self self.imdbSelectionModel = QItemSelectionModel(self.imdbModel) self.ui.searchResultsView.setSelectionModel(self.imdbSelectionModel) self.imdbSelectionModel.selectionChanged.connect( self.onIMDBChangeSelection) self.ui.searchResultsView.activated.connect(self.onOkButton)
def __init__(self, elements=None, parent=None): """ Common interface for the labelListModel, the boxListModel, and the cropListModel see concrete implementations for details :param elements: :param parent: """ QAbstractTableModel.__init__(self, parent) if elements is None: elements = [] self._elements = list(elements) self._selectionModel = QItemSelectionModel(self) def onSelectionChanged(selected, deselected): if selected: ind = selected[0].indexes() if len(ind) > 0: self.elementSelected.emit(ind[0].row()) self._selectionModel.selectionChanged.connect(onSelectionChanged) self._allowRemove = True self._toolTipSuffixes = {} self.unremovable_rows = [ ] # rows in this list cannot be removed from the gui,
def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.splitter) self.__ColCount = 6 #列数=6 self.itemModel = QStandardItemModel(5, self.__ColCount, self) # 数据模型,10行6列 self.selectionModel = QItemSelectionModel(self.itemModel) #Item选择模型 self.selectionModel.currentChanged.connect(self.do_curChanged) self.__lastColumnTitle = "测井取样" self.__lastColumnFlags = (Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) ##tableView设置 self.ui.tableView.setModel(self.itemModel) #设置数据模型 self.ui.tableView.setSelectionModel(self.selectionModel) #设置选择模型 oneOrMore = QAbstractItemView.ExtendedSelection self.ui.tableView.setSelectionMode(oneOrMore) #可多选 itemOrRow = QAbstractItemView.SelectItems self.ui.tableView.setSelectionBehavior(itemOrRow) #单元格选择 self.ui.tableView.verticalHeader().setDefaultSectionSize(22) #缺省行高 self.ui.tableView.setAlternatingRowColors(True) #交替行颜色 self.ui.tableView.setEnabled(False) #先禁用tableView self.__buildStatusBar()
def onAnnotationsLoaded(self): self.labeltool.model().dirtyChanged.connect(self.onModelDirtyChanged) self.onModelDirtyChanged(self.labeltool.model().dirty()) self.treeview.setModel(self.labeltool.model()) self.scene.setModel(self.labeltool.model()) self.selectionmodel = QItemSelectionModel(self.labeltool.model()) self.treeview.setSelectionModel(self.selectionmodel) self.treeview.selectionModel().currentChanged.connect(self.labeltool.setCurrentImage) self.property_editor.onModelChanged(self.labeltool.model()) self.startBackgroundLoading()
def __openTable(self): ##打开数据表 self.tabModel = QSqlRelationalTableModel(self, self.DB) #数据表 self.tabModel.setTable("studInfo") #设置数据表 self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit ) #数据保存方式,OnManualSubmit , OnRowChange self.tabModel.setSort(self.tabModel.fieldIndex("studID"), Qt.AscendingOrder) #排序 if (self.tabModel.select() == False): #查询数据失败 QMessageBox.critical( self, "错误信息", "打开数据表错误,错误信息\n" + self.tabModel.lastError().text()) return self.__getFieldNames() #获取字段名和序号 ##字段显示名 self.tabModel.setHeaderData(self.fldNum["studID"], Qt.Horizontal, "学号") self.tabModel.setHeaderData(self.fldNum["name"], Qt.Horizontal, "姓名") self.tabModel.setHeaderData(self.fldNum["gender"], Qt.Horizontal, "性别") self.tabModel.setHeaderData(self.fldNum["departID"], Qt.Horizontal, "学院") self.tabModel.setHeaderData(self.fldNum["majorID"], Qt.Horizontal, "专业") ## 设置代码字段的查询关系数据表 self.tabModel.setRelation(self.fldNum["departID"], QSqlRelation("departments", "departID", "department")) #学院 self.tabModel.setRelation(self.fldNum["majorID"], QSqlRelation("majors", "majorID", "major")) #专业 self.selModel = QItemSelectionModel(self.tabModel) #关联选择模型 ##selModel当前项变化时触发currentChanged信号 self.selModel.currentChanged.connect(self.do_currentChanged) ##选择行变化时 ## self.selModel.currentRowChanged.connect(self.do_currentRowChanged) self.ui.tableView.setModel(self.tabModel) #设置数据模型 self.ui.tableView.setSelectionModel(self.selModel) #设置选择模型 delgate = QSqlRelationalDelegate(self.ui.tableView) self.ui.tableView.setItemDelegate(delgate) #为关系型字段设置缺省代理组件 self.tabModel.select() #必须重新查询数据 ##更新actions和界面组件的使能状态 self.ui.actOpenDB.setEnabled(False) self.ui.actRecAppend.setEnabled(True) self.ui.actRecInsert.setEnabled(True) self.ui.actRecDelete.setEnabled(True) self.ui.actFields.setEnabled(True)
def __init__(self, parent=None): super(GraphDigitGraphicsView, self).__init__(parent) # scene rect = QRectF(0, 0, 300, 400) self.scene = QGraphicsScene(rect) # 创建场景 参数:场景区域 self.setScene(self.scene) # 给视图窗口设置场景 # image self.graphicsPixmapItem = QGraphicsPixmapItem() # chart image self.scene.addItem(self.graphicsPixmapItem) # setAntialias self.setRenderHint(QPainter.Antialiasing) # image object stored in project data # item objects storage self.axesxObjs = {} self.axesyObjs = {} self.gridObjs = [] self.curveObjs = {} self.pointObjs = {} # axis coord stored in project data # grid setting stored in project data # grid position self.gridxpos = [] self.gridypos = [] # axes curve and point datamodel self.axesxModel = QStandardItemModel() self.axesyModel = QStandardItemModel() self.axesxSelectModel = QItemSelectionModel(self.axesxModel) self.axesySelectModel = QItemSelectionModel(self.axesyModel) self.curveModel = QStandardItemModel() self.pointsModel = QStandardItemModel() self.curveModel.setHorizontalHeaderLabels( ["current", "name", "visible"]) self.pointsModel.setHorizontalHeaderLabels(["order", "x", "y"]) self.axesxModel.setHorizontalHeaderLabels(["position", "x"]) self.axesyModel.setHorizontalHeaderLabels(["position", "y"]) ### self.xNo = 0 self.yNo = 0 ### self.mode = OpMode.default # data manage self.proj = Digi() # init self.currentCurve = None self.pointsModel.itemChanged.connect(self.changePointOrder) self.curveModel.itemChanged.connect(self.changeCurveVisible) self.scene.selectionChanged.connect(self.slotSceneSeletChanged) # state self._lastCurve = None
def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建Ui对象 self.ui.setupUi(self) #构造UI self.__ColCount = 6 #列数 self.itemModel = QStandardItemModel( 10, self.__ColCount, self) #创建QStandardItemModel类型的数据模型,指定行列值 ''' setSelectionBehavior() 此属性保存视图使用的选择行为。 此属性保存选择是根据单个项目,行还是列进行的 #QItemSelectionModel() 此属性保存视图在哪种选择模式下运行。 #此属性控制用户是否可以选择一个或多个项目,并且在多个项目选择中控制选择是否必须是连续范围的项目 ''' self.selectionModel = QItemSelectionModel(self.itemModel) self.selectionModel.currentChanged.connect( self.do_curChanged) #单元格选择发生变化时会发射此信号 self.__lastColumnTitle = "" #设置最后一列的标题,可以是空 self.__lastColumnFlags = (Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) #设置tableView属性 self.ui.tableView.setModel(self.itemModel) #数据模型 self.ui.tableView.setSelectionModel(self.selectionModel) #选择模型 oneOrMore = QAbstractItemView.ExtendedSelection #选择模式->多选模式 self.ui.tableView.setSelectionMode(oneOrMore) #多选模式 itemOrRow = QAbstractItemView.SelectItems #项选择模式->单元格选择 self.ui.tableView.setSelectionBehavior(itemOrRow) #单元格选择 self.ui.tableView.verticalHeader().setDefaultSectionSize(22) self.ui.tableView.setAlternatingRowColors(True) #交替行颜色 self.ui.tableView.setEnabled(False) #设置默认禁用tabelView self.ui.actFontBold.setCheckable(False) self.setCentralWidget(self.ui.splitter) #设置中心组件 # self.setCentralWidget(self.ui.tableView) self.__buildStatusBar() self.spinCeshen = QmyFloatSpinDelegate(0, 10000, 0, self) self.spinLength = QmyFloatSpinDelegate(0, 6000, 2, self) self.spinDegree = QmyFloatSpinDelegate(0, 360, 1, self) self.ui.tableView.setItemDelegateForColumn(0, self.spinCeshen) self.ui.tableView.setItemDelegateForColumn(1, self.spinLength) self.ui.tableView.setItemDelegateForColumn(3, self.spinLength) self.ui.tableView.setItemDelegateForColumn(2, self.spinDegree) qualities = ["优", "良", "合格", "不合格"] self.comboDelegate = QmyComboBoxDelegate(self) self.comboDelegate.setItems(qualities, False) self.ui.tableView.setItemDelegateForColumn(4, self.comboDelegate)
def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setCentralWidget(self.ui.qSplitter) self.__ColCount = 6 self.itemModel = QStandardItemModel(5, self.__ColCount, self) self.selectionModel = QItemSelectionModel(self.itemModel) self.selectionModel.currentChanged.connect(self.do_curChanged) self.__lastColumnTitle = "测井取样" self.__lastColumnFlags = (Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) self.ui.qTableView.setModel(self.itemModel) self.ui.qTableView.setSelectionModel(self.selectionModel) oneOrMore = QAbstractItemView.ExtendedSelection self.ui.qTableView.setSelectionMode(oneOrMore) itemOrRow = QAbstractItemView.SelectItems self.ui.qTableView.setSelectionBehavior(itemOrRow) self.ui.qTableView.verticalHeader().setDefaultSectionSize(22) self.ui.qTableView.setAlternatingRowColors(True) self.ui.qTableView.setEnabled(False) self.qLabel1 = QLabel("当前单元格:", self) self.qLabel1.setMinimumWidth(180) self.qLabel2 = QLabel("单元格内容:", self) self.qLabel2.setMinimumWidth(150) self.qLabel3 = QLabel("当前文件:", self) self.ui.qStatusBar.addWidget(self.qLabel1) self.ui.qStatusBar.addWidget(self.qLabel2) self.ui.qStatusBar.addPermanentWidget(self.qLabel3) self.spinCeshen = QmyFloatSpinDelegate(0, 10000, 0, self) self.spinLength = QmyFloatSpinDelegate(0, 6000, 2, self) self.spinDegree = QmyFloatSpinDelegate(0, 360, 1, self) self.ui.qTableView.setItemDelegateForColumn(0, self.spinCeshen) self.ui.qTableView.setItemDelegateForColumn(1, self.spinLength) self.ui.qTableView.setItemDelegateForColumn(3, self.spinLength) self.ui.qTableView.setItemDelegateForColumn(2, self.spinDegree) qualities = ["优", "良", "合格", "不合格"] self.comboDelegate = QmyComboBoxDelegate(self) self.comboDelegate.setItems(qualities, False) self.ui.qTableView.setItemDelegateForColumn(4, self.comboDelegate)
def __init__(self, project, type_, parent=None): """ Constructor @param project reference to the project object @param type_ project browser type (string) @param parent parent widget of this browser """ QTreeView.__init__(self, parent) self.project = project self._model = project.getModel() self._sortModel = ProjectBrowserSortFilterProxyModel(type_) self._sortModel.setSourceModel(self._model) self.setModel(self._sortModel) self.selectedItemsFilter = [ProjectBrowserFileItem] # contains codes for special menu entries # 1 = specials for Others browser self.specialMenuEntries = [] self.isTranslationsBrowser = False self.expandedNames = [] self.SelectFlags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.Select | QItemSelectionModel.Rows) self.DeselectFlags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.Deselect | QItemSelectionModel.Rows) self._activating = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._contextMenuRequested) self.activated.connect(self._openItem) self._model.rowsInserted.connect(self.__modelRowsInserted) self._connectExpandedCollapsed() self._createPopupMenus() self.currentItemName = None self._init() # perform common initialization tasks self._keyboardSearchString = "" self._keyboardSearchTimer = QElapsedTimer() self._keyboardSearchTimer.invalidate() self._initHookMethods() # perform initialization of the hooks self.hooksMenuEntries = {}
def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.splitter) self.__buildStatusBar() self.COL_COUNT = 6 #常数,列数=6 self.itemModel = QStandardItemModel(5, self.COL_COUNT, self) # 数据模型,10行6列 ## headerList=["测深(m)","垂深(m)","方位(°)","总位移(m)","固井质量","测井取样"] ## self.itemModel.setHorizontalHeaderLabels(headerList) #设置表头文字 self.selectionModel = QItemSelectionModel(self.itemModel) #Item选择模型 self.selectionModel.currentChanged.connect(self.do_currentChanged) self.__lastColumnFlags = (Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) self.__lastColumnTitle = "测井取样" #为tableView设置数据模型 self.ui.tableView.setModel(self.itemModel) #设置数据模型 self.ui.tableView.setSelectionModel(self.selectionModel) #设置选择模型 oneOrMore = QAbstractItemView.ExtendedSelection self.ui.tableView.setSelectionMode(oneOrMore) #可多选 itemOrRow = QAbstractItemView.SelectItems self.ui.tableView.setSelectionBehavior(itemOrRow) #单元格选择 self.ui.tableView.verticalHeader().setDefaultSectionSize(22) #缺省行高 self.ui.tableView.setEnabled(False) #先禁用tableView ## self.__resetTable(5) #创建自定义代理组件并设置 self.spinCeShen = QmyFloatSpinDelegate(0, 10000, 0, self) #用于 测深 self.spinLength = QmyFloatSpinDelegate(0, 6000, 2, self) #垂深,总位移 self.spinDegree = QmyFloatSpinDelegate(0, 360, 1, self) #用于 方位 self.ui.tableView.setItemDelegateForColumn(0, self.spinCeShen) #测深 self.ui.tableView.setItemDelegateForColumn(1, self.spinLength) #垂深 self.ui.tableView.setItemDelegateForColumn(3, self.spinLength) #总位移 self.ui.tableView.setItemDelegateForColumn(2, self.spinDegree) #方位角 qualities = ["优", "良", "合格", "不合格"] self.comboDelegate = QmyComboBoxDelegate(self) self.comboDelegate.setItems(qualities, False) #不可编辑 self.ui.tableView.setItemDelegateForColumn(4, self.comboDelegate) #固井质量
def __init__(self, parent=None): QAbstractListModel.__init__(self, parent) self._layerStack = [] self.selectionModel = QItemSelectionModel(self) self.selectionModel.selectionChanged.connect(self.updateGUI) self.selectionModel.selectionChanged.connect(self._onSelectionChanged) self._movingRows = False QTimer.singleShot(0, self.updateGUI) def _handleRemovedLayer(layer): # Layerstacks *own* the layers they hold, and thus are # responsible for cleaning them up when they are removed: layer.clean_up() self.layerRemoved.connect(_handleRemovedLayer)
def __init__(self, elements=None, parent=None): ''' Common interface for the labelListModel, the boxListModel, and the cropListModel see concrete implementations for details :param elements: :param parent: ''' QAbstractTableModel.__init__(self, parent) if elements is None: elements = [] self._elements = list(elements) self._selectionModel = QItemSelectionModel(self) def onSelectionChanged(selected, deselected): if selected: ind = selected[0].indexes() if len(ind)>0: self.elementSelected.emit(ind[0].row()) self._selectionModel.selectionChanged.connect(onSelectionChanged) self._allowRemove = True self._toolTipSuffixes = {} self.unremovable_rows=[] #rows in this list cannot be removed from the gui,
def __init__(self, treeManipulate, tabnumber): self.treeManipulate = treeManipulate self.tabnumber = tabnumber self.tvspecruleview = None self.bspecrulehelp = None self.setUiInit() self.helptext = self.treeManipulate.main.specrulehelp #build empty model for data and the selection self.specrulemodel = SpecRuleStandardItemModel(self.tvspecruleview, self) self.specrulemodel.setHorizontalHeaderLabels( ["Node", "uid", "Condition", "result", "comment"]) self.specruleselectionmodel = QItemSelectionModel(self.specrulemodel) #set model to tableview self.tvspecruleview.setModel(self.specrulemodel) self.tvspecruleview.setSelectionModel(self.specruleselectionmodel) #signals self.bspecrulehelp.clicked.connect(self.help) self.specrulemodel.itemChanged.connect(self.changeSpecRule) self.treeManipulate.treeModel.nameChangedSignal.connect( self.changeSpecRuleNodeName) #resize self.resz() #variables self.changeOnce = True
def main(args): app = QApplication(args) page = QSplitter() data = Model(1000, 10, page) selections = QItemSelectionModel(data) table = QTableView() table.setModel(data) table.setSelectionModel(selections) table.horizontalHeader().setSectionsMovable(True) table.verticalHeader().setSectionsMovable(True) # Set StaticContents to enable minimal repaints on resizes. table.viewport().setAttribute(Qt.WA_StaticContents) page.addWidget(table) tree = QTreeView() tree.setModel(data) tree.setSelectionModel(selections) tree.setUniformRowHeights(True) tree.header().setStretchLastSection(False) tree.viewport().setAttribute(Qt.WA_StaticContents) # Disable the focus rect to get minimal repaints when scrolling on Mac. tree.setAttribute(Qt.WA_MacShowFocusRect, False) page.addWidget(tree) list = QListView() list.setModel(data) list.setSelectionModel(selections) list.setViewMode(QListView.IconMode) list.setSelectionMode(QAbstractItemView.ExtendedSelection) list.setAlternatingRowColors(False) list.viewport().setAttribute(Qt.WA_StaticContents) list.setAttribute(Qt.WA_MacShowFocusRect, False) page.addWidget(list) page.setWindowIcon(QIcon(images_dir + "/interview.png")) page.setWindowTitle("Interview") page.show() return app.exec_()
def __init__(self, orm): super().__init__() self.setupUi(self) self.orm = orm self.accounts = ListModel() self.accountsView.setModel(self.accounts) self.selection = QItemSelectionModel(self.accounts) self.accountsView.setSelectionModel(self.selection) self.selection.currentRowChanged.connect(self.selection_changed) self.typeBox.addItems(ACCOUNT_TYPES) self.typeBox.currentTextChanged.connect(self.type_changed) self.closedBox.stateChanged.connect(self.closed_changed) self.exBudgetBox.stateChanged.connect(self.budget_changed) self.addAccountButton.clicked.connect(self.add_account) self.deleteAccountButton.clicked.connect(self.delete_account) for acc in self.orm.fetch_accounts(): self.accounts.addItem(acc)
def __setRowSelected(self, index, selected=True): """ Private slot to select a complete row. @param index index determining the row to be selected (QModelIndex) @param selected flag indicating the action (bool) """ if not index.isValid(): return if selected: flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) else: flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.Deselect | QItemSelectionModel.Rows) self.selectionModel().select(index, flags)
def __openTable(self): self.tabModel = QSqlRelationalTableModel(self, self.DB) self.tabModel.setTable("studInfo") self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit) self.tabModel.setSort(self.tabModel.fieldIndex("studID"), Qt.AscendingOrder) if (self.tabModel.select() == False): QMessageBox.critical( self, "错误信息", "打开数据表错误,错误信息\n" + self.tabModel.lastError().text()) return self.__getFieldNames() self.tabModel.setHeaderData(self.fldNum["studID"], Qt.Horizontal, "学号") self.tabModel.setHeaderData(self.fldNum["name"], Qt.Horizontal, "姓名") self.tabModel.setHeaderData(self.fldNum["gender"], Qt.Horizontal, "性别") self.tabModel.setHeaderData(self.fldNum["departID"], Qt.Horizontal, "学院") self.tabModel.setHeaderData(self.fldNum["majorID"], Qt.Horizontal, "专业") self.tabModel.setRelation( self.fldNum["departID"], QSqlRelation("departments", "departID", "department")) self.tabModel.setRelation(self.fldNum["majorID"], QSqlRelation("majors", "majorID", "major")) self.selModel = QItemSelectionModel(self.tabModel) self.selModel.currentChanged.connect(self.do_currentChanged) self.ui.tableView.setModel(self.tabModel) self.ui.tableView.setSelectionModel(self.selModel) delgate = QSqlRelationalDelegate(self.ui.tableView) self.ui.tableView.setItemDelegate(delgate) self.tabModel.select() self.ui.actOpenDB.setEnabled(False) self.ui.actRecAppend.setEnabled(True) self.ui.actRecInsert.setEnabled(True) self.ui.actRecDelete.setEnabled(True) self.ui.actFields.setEnabled(True)
def _contextMenuRequested(self, coord): """ Protected slot to show the context menu of the listview. @param coord the position of the mouse pointer (QPoint) """ categories = self.getSelectedItemsCountCategorized([ BrowserDirectoryItem, BrowserFileItem, BrowserClassItem, BrowserMethodItem ]) cnt = categories["sum"] bfcnt = categories[str(BrowserFileItem)] if cnt > 1 and cnt == bfcnt: self.multiMenu.popup(self.mapToGlobal(coord)) else: index = self.indexAt(coord) if index.isValid(): self.setCurrentIndex(index) flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) self.selectionModel().select(index, flags) itm = self.model().item(index) coord = self.mapToGlobal(coord) if isinstance(itm, BrowserFileItem): if itm.isPython3File(): if itm.fileName().endswith('.py'): self.unittestAct.setEnabled(True) else: self.unittestAct.setEnabled(False) self.sourceMenu.popup(coord) else: self.editPixmapAct.setVisible(itm.isPixmapFile()) self.menu.popup(coord) elif isinstance(itm, BrowserClassItem) or \ isinstance(itm, BrowserMethodItem) or \ isinstance(itm, BrowserImportItem): self.editPixmapAct.setVisible(False) self.menu.popup(coord) elif isinstance(itm, BrowserClassAttributeItem): self.attributeMenu.popup(coord) elif isinstance(itm, BrowserDirectoryItem): if not index.parent().isValid(): self.removeFromToplevelAct.setEnabled(True) self.addAsTopLevelAct.setEnabled(False) else: self.removeFromToplevelAct.setEnabled(False) self.addAsTopLevelAct.setEnabled(True) self.dirMenu.popup(coord) else: self.backMenu.popup(coord) else: self.backMenu.popup(self.mapToGlobal(coord))
def setRoot(self, root: SequencerStep) -> None: """ Populate the widget with a sequence of acquisition steps Args: root: The Root step of the acquisition sequence. All other steps are children of this step. """ self.setModel(TreeModel(root)) self.setSelectionModel(QItemSelectionModel(self.model(), self)) self.selectionModel().selectionChanged.connect(self._selectionChanged) self.selectionModel().currentChanged.connect(self._currentChanged)
def setupControls(self): """This method connects all controls in the UI to their callbacks. It is called in ad_action""" portNames = [Tachy2Gis.NO_PORT] portNames.extend( [port.portName() for port in QSerialPortInfo.availablePorts()]) self.dlg.portComboBox.addItems(portNames) self.dlg.portComboBox.currentIndexChanged.connect(self.connectSerial) self.dlg.logFileButton.clicked.connect(self.setLog) self.dlg.deleteAllButton.clicked.connect(self.clearCanvas) self.dlg.finished.connect(self.mapTool.clear) self.dlg.dumpButton.clicked.connect(self.dump) self.dlg.deleteVertexButton.clicked.connect(self.mapTool.deleteVertex) self.dlg.vertexTableView.setModel(self.vertexList) self.dlg.vertexTableView.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) self.dlg.vertexTableView.setSelectionModel( QItemSelectionModel(self.vertexList)) self.dlg.vertexTableView.selectionModel().selectionChanged.connect( self.mapTool.selectVertex) self.dlg.finished.connect(self.restoreTool) self.dlg.accepted.connect(self.restoreTool) self.dlg.rejected.connect(self.restoreTool) self.dlg.sourceLayerComboBox.setFilters( QgsMapLayerProxyModel.VectorLayer | QgsMapLayerProxyModel.WritableLayer) self.dlg.sourceLayerComboBox.setLayer(self.iface.activeLayer()) self.dlg.sourceLayerComboBox.layerChanged.connect(self.setActiveLayer) self.dlg.sourceLayerComboBox.layerChanged.connect(self.mapTool.clear) self.fieldDialog.targetLayerComboBox.layerChanged.connect( self.targetChanged) self.vertexList.layoutChanged.connect(self.dumpEnabled) self.fieldDialog.buttonBox.accepted.connect( self.extent_provider.add_feature) self.dlg.zoomResetButton.clicked.connect(self.extent_provider.reset) self.dlg.zoomModeComboBox.addItems([ 'Layer', 'Last feature', 'Last 2 features', 'Last 4 features', 'Last 8 features', ]) self.dlg.zoomModeComboBox.currentIndexChanged.connect( self.extent_provider.set_mode) self.dlg.zoomActiveCheckBox.stateChanged.connect( self.auto_zoomer.set_active) self.extent_provider.ready.connect(self.auto_zoomer.apply)
def _selectSingleItem(self, index): """ Protected method to select a single item. @param index index of item to be selected (QModelIndex) """ if index.isValid(): self.setCurrentIndex(index) flags = QItemSelectionModel.SelectionFlags( QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) self.selectionModel().select(index, flags)
def __init__(self, parent=None): super().__init__(parent) # initialize class attributes self._INPUTS_FIXED_WIDTH = 180 self._BUTTON_MIN_WIDTH = 80 self._OXYGEN_PATH_32 = os.path.join("resources", "icons", "oxygen", "32") # locale and language settings self.language = self.locale().name()[:2] self.qtTl = QTranslator() self.appTl = QTranslator() self.switchTranslator(self.qtTl, "qtbase", self.language) self.switchTranslator(self.appTl, "wuchshuellenrechner", self.language) # TODO(th) self.model = TreeModel() # setup gui self.setMinimumSize(1200, 760) self.createActions() self.createMainMenu() # plot widget self.plotWidget = VariantPlotView() self.plotWidget.setModel(self.model) # create vertical splitter splitter = QSplitter(Qt.Vertical) splitter.setContentsMargins(11, 11, 11, 11) splitter.addWidget(self.createEditBox()) splitter.addWidget(self.plotWidget) self.setCentralWidget(splitter) self.dataWidget.setModel(self.model) selectionModel = QItemSelectionModel(self.model) self.dataWidget.setSelectionModel(selectionModel) self.plotWidget.setSelectionModel(selectionModel) self.retranslateUi() self.model.dataChanged.connect(self.updateInputs) self.model.itemsInserted.connect(self.taxInput.setDisabled) self.model.allItemsRemoved.connect(self.taxInput.setEnabled) self.operationInput.textChanged.connect(self.updateOperation) self.districtInput.textChanged.connect(self.updateDistrict) self.managerInput.textChanged.connect(self.updateManager) self.locationInput.textChanged.connect(self.updateLocation) self.taxInput.stateChanged.connect(self.updateTax)
def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_QWFormTable() self.ui.setupUi(self) self.__dlgSetHeaders = None self.setAutoFillBackground(True) self.setCentralWidget(self.ui.qTableView) self.itemModel = QStandardItemModel(10, 5, self) self.selectionModel = QItemSelectionModel(self.itemModel) self.ui.qTableView.setModel(self.itemModel) self.ui.qTableView.setSelectionModel(self.selectionModel)
def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.__dlgSetHeaders = None self.setCentralWidget(self.ui.qTableView) self.qLabel1 = QLabel("当前单元格:", self) self.qLabel1.setMinimumWidth(180) self.ui.qStatusBar.addWidget(self.qLabel1) self.qLabel2 = QLabel("单元格内容:", self) self.qLabel2.setMinimumWidth(200) self.ui.qStatusBar.addWidget(self.qLabel2) self.itemModel = QStandardItemModel(10, 5, self) self.selectionModel = QItemSelectionModel(self.itemModel) self.selectionModel.currentChanged.connect( self.do_currentChanged) # 显示状态栏信息 self.ui.qTableView.setModel(self.itemModel) self.ui.qTableView.setSelectionModel(self.selectionModel)
def __openTable(self): self.qryModel = QSqlQueryModel(self) self.qryModel.setQuery( '''SELECT empNo, Name, Gender, Birthday, Province, Department, Salary FROM employee ORDER BY empNo''' ) if self.qryModel.lastError().isValid(): QMessageBox.critical( self, "错误", "数据表查询错误,错误信息\n" + self.qryModel.lastError().text()) return self.ui.statusBar.showMessage("记录条数:%d" % self.qryModel.rowCount()) self.__getFieldNames() self.qryModel.setHeaderData(0, Qt.Horizontal, "工号") self.qryModel.setHeaderData(1, Qt.Horizontal, "姓名") self.qryModel.setHeaderData(2, Qt.Horizontal, "性别") self.qryModel.setHeaderData(3, Qt.Horizontal, "出生日期") self.qryModel.setHeaderData(4, Qt.Horizontal, "省份") self.qryModel.setHeaderData(5, Qt.Horizontal, "部门") self.qryModel.setHeaderData(6, Qt.Horizontal, "工资") self.mapper = QDataWidgetMapper() self.mapper.setModel(self.qryModel) self.mapper.addMapping(self.ui.dbSpinEmpNo, 0) self.mapper.addMapping(self.ui.dbEditName, 1) self.mapper.addMapping(self.ui.dbComboSex, 2) self.mapper.addMapping(self.ui.dbEditBirth, 3) self.mapper.addMapping(self.ui.dbComboProvince, 4) self.mapper.addMapping(self.ui.dbComboDep, 5) self.mapper.addMapping(self.ui.dbSpinSalary, 6) self.mapper.toFirst() self.selModel = QItemSelectionModel(self.qryModel) self.selModel.currentRowChanged.connect(self.do_currentRowChanged) self.ui.tableView.setModel(self.qryModel) self.ui.tableView.setSelectionModel(self.selModel) self.ui.actOpenDB.setEnabled(False)
def _on_move_down_button_click(self, event: QMouseEvent) -> None: style = self._selected_style assert style is not None idx = style.index with self._api.undo.capture(): self._api.subs.styles[idx:idx + 1] = [] self._api.subs.styles[idx + 1:idx + 1] = [style] self._styles_list_view.selectionModel().select( self._model.index(idx + 1, 0), QItemSelectionModel.SelectionFlag( QItemSelectionModel.SelectionFlag.Clear | QItemSelectionModel.SelectionFlag.Select), )
class LayerStackModel(QAbstractListModel): canMoveSelectedUp = pyqtSignal("bool") canMoveSelectedDown = pyqtSignal("bool") canDeleteSelected = pyqtSignal("bool") orderChanged = pyqtSignal() layerAdded = pyqtSignal(Layer, int) # is now in row layerRemoved = pyqtSignal(Layer, int) # was in row stackCleared = pyqtSignal() def __init__(self, parent=None): QAbstractListModel.__init__(self, parent) self._layerStack = [] self.selectionModel = QItemSelectionModel(self) self.selectionModel.selectionChanged.connect(self.updateGUI) self.selectionModel.selectionChanged.connect(self._onSelectionChanged) self._movingRows = False QTimer.singleShot(0, self.updateGUI) def _handleRemovedLayer(layer): # Layerstacks *own* the layers they hold, and thus are # responsible for cleaning them up when they are removed: layer.clean_up() self.layerRemoved.connect(_handleRemovedLayer) #### ## High level API to manipulate the layerstack ### def __len__(self): return self.rowCount() def __repr__(self): return "<LayerStackModel: layerStack='%r'>" % (self._layerStack,) def __getitem__(self, i): return self._layerStack[i] def __iter__(self): return self._layerStack.__iter__() def layerIndex(self, layer): # note that the 'index' function already has a different implementation # from Qt side return self._layerStack.index(layer) def findMatchingIndex(self, func): """Call the given function with each layer and return the index of the first layer for which f is True.""" for index, layer in enumerate(self._layerStack): if func(layer): return index raise ValueError("No matching layer in stack.") def append(self, data): self.insert(0, data) def clear(self): if len(self) > 0: self.removeRows(0, len(self)) self.stackCleared.emit() def insert(self, index, data): """ Insert a layer into this layer stack, which *takes ownership* of the layer. """ assert isinstance(data, Layer), "Only Layers can be added to a LayerStackModel" self.insertRow(index) self.setData(self.index(index), data) if self.selectedRow() >= 0: self.selectionModel.select(self.index(self.selectedRow()), QItemSelectionModel.Deselect) self.selectionModel.select(self.index(index), QItemSelectionModel.Select) data.changed.connect(functools.partial(self._onLayerChanged, self.index(index))) index = self._layerStack.index(data) self.layerAdded.emit(data, index) self.updateGUI() def selectRow(self, row): already_selected_rows = self.selectionModel.selectedRows() if len(already_selected_rows) == 1 and row == already_selected_rows[0]: # Nothing to do if this row is already selected return self.selectionModel.clear() self.selectionModel.setCurrentIndex(self.index(row), QItemSelectionModel.SelectCurrent) def deleteSelected(self): num_rows = len(self.selectionModel.selectedRows()) assert num_rows == 1, "Can't delete selected row: {} layers are currently selected.".format(num_rows) row = self.selectionModel.selectedRows()[0] layer = self._layerStack[row.row()] assert ( not layer._cleaned_up ), "This layer ({}) has already been cleaned up. Shouldn't it already be removed from the layerstack?".format( layer.name ) self.removeRow(row.row()) if self.rowCount() > 0: self.selectionModel.select(self.index(0), QItemSelectionModel.Select) self.layerRemoved.emit(layer, row.row()) self.updateGUI() def moveSelectedUp(self): assert len(self.selectionModel.selectedRows()) == 1 row = self.selectionModel.selectedRows()[0] if row.row() != 0: oldRow = row.row() newRow = oldRow - 1 self._moveToRow(oldRow, newRow) def moveSelectedDown(self): assert len(self.selectionModel.selectedRows()) == 1 row = self.selectionModel.selectedRows()[0] if row.row() != self.rowCount() - 1: oldRow = row.row() newRow = oldRow + 1 self._moveToRow(oldRow, newRow) def moveSelectedToTop(self): assert len(self.selectionModel.selectedRows()) == 1 row = self.selectionModel.selectedRows()[0] if row.row() != 0: oldRow = row.row() newRow = 0 self._moveToRow(oldRow, newRow) def moveSelectedToBottom(self): assert len(self.selectionModel.selectedRows()) == 1 row = self.selectionModel.selectedRows()[0] if row.row() != self.rowCount() - 1: oldRow = row.row() newRow = self.rowCount() - 1 self._moveToRow(oldRow, newRow) def moveSelectedToRow(self, newRow): assert len(self.selectionModel.selectedRows()) == 1 row = self.selectionModel.selectedRows()[0] if row.row() != newRow: oldRow = row.row() self._moveToRow(oldRow, newRow) def _moveToRow(self, oldRow, newRow): d = self._layerStack[oldRow] self.removeRow(oldRow) self.insertRow(newRow) self.setData(self.index(newRow), d) self.selectionModel.select(self.index(newRow), QItemSelectionModel.Select) self.orderChanged.emit() self.updateGUI() #### ## Low level API. To add, remove etc. layers use the high level API from above. #### def updateGUI(self): self.canMoveSelectedUp.emit(self.selectedRow() > 0) self.canMoveSelectedDown.emit(self.selectedRow() < self.rowCount() - 1) self.canDeleteSelected.emit(self.rowCount() > 0) self.wantsUpdate() def selectedRow(self): selected = self.selectionModel.selectedRows() if len(selected) == 1: return selected[0].row() return -1 def selectedIndex(self): row = self.selectedRow() if row >= 0: return self.index(self.selectedRow()) else: return QModelIndex() def rowCount(self, parent=QModelIndex()): if not parent.isValid(): return len(self._layerStack) return 0 def insertRows(self, row, count, parent=QModelIndex()): """Insert empty rows in the stack. DO NOT USE THIS METHOD TO INSERT NEW LAYERS! Always use the insert() or append() method. """ if parent.isValid(): return False oldRowCount = self.rowCount() # for some reason, row can be negative! beginRow = max(0, row) endRow = min(beginRow + count - 1, len(self._layerStack)) self.beginInsertRows(parent, beginRow, endRow) while beginRow <= endRow: self._layerStack.insert(row, Layer(datasources=[])) beginRow += 1 self.endInsertRows() assert self.rowCount() == oldRowCount + 1, "oldRowCount = %d, self.rowCount() = %d" % ( oldRowCount, self.rowCount(), ) return True def removeRows(self, row, count, parent=QModelIndex()): """Remove rows from the stack. DO NOT USE THIS METHOD TO REMOVE LAYERS! Use the deleteSelected() method instead. """ if parent.isValid(): return False if row + count <= 0 or row >= len(self._layerStack): return False oldRowCount = self.rowCount() beginRow = max(0, row) endRow = min(row + count - 1, len(self._layerStack) - 1) self.beginRemoveRows(parent, beginRow, endRow) while beginRow <= endRow: del self._layerStack[row] beginRow += 1 self.endRemoveRows() return True def flags(self, index): defaultFlags = Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled if index.isValid(): return Qt.ItemIsDragEnabled | defaultFlags else: return Qt.ItemIsDropEnabled | defaultFlags def supportedDropActions(self): return Qt.MoveAction def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return None if index.row() >= len(self._layerStack): return None if role == Qt.DisplayRole or role == Qt.EditRole: return self._layerStack[index.row()] elif role == Qt.ToolTipRole: return self._layerStack[index.row()].toolTip() else: return None def setData(self, index, value, role=Qt.EditRole): """Replace one layer with another. DO NOT USE THIS METHOD TO INSERT NEW LAYERS! Use deleteSelected() followed by insert() or append(). """ if role == Qt.EditRole: layer = value if not isinstance(value, Layer): layer = value self._layerStack[index.row()] = layer self.dataChanged.emit(index, index) return True elif role == Qt.ToolTipRole: self._layerStack[index.row()].setToolTip() return True return False def headerData(self, section, orientation, role=Qt.DisplayRole): if role != Qt.DisplayRole: return None if orientation == Qt.Horizontal: return "Column %r" % section else: return "Row %r" % section def wantsUpdate(self): self.layoutChanged.emit() def _onLayerChanged(self, idx): self.dataChanged.emit(idx, idx) self.updateGUI() def _onSelectionChanged(self, selected, deselected): for idx in deselected.indexes(): self[idx.row()].setActive(False) for idx in selected.indexes(): self[idx.row()].setActive(True)
class imdbSearchDialog(QDialog): def __init__(self, parent, main): QDialog.__init__(self, parent) self.ui = Ui_IMDBSearchDialog() self.ui.setupUi(self) self._main = main self.ui.searchMovieButton.clicked.connect(self.onSearchMovieButton) self.ui.movieInfoButton.clicked.connect(self.onMovieInfoButton) self.ui.okButton.clicked.connect(self.onOkButton) self.ui.cancelButton.clicked.connect(self.onCancelButton) header = self.ui.searchResultsView.horizontalHeader() header.setSectionResizeMode(QHeaderView.Stretch) header.hide() self.ui.searchResultsView.verticalHeader().hide() self.imdbModel = ImdbListModel(self) self.ui.searchResultsView.setModel(self.imdbModel) # FIXME: This connection should be cleaner. self.imdbModel._main = self self.imdbSelectionModel = QItemSelectionModel(self.imdbModel) self.ui.searchResultsView.setSelectionModel(self.imdbSelectionModel) self.imdbSelectionModel.selectionChanged.connect( self.onIMDBChangeSelection) self.ui.searchResultsView.activated.connect(self.onOkButton) @pyqtSlot() def onSearchMovieButton(self): if not self.ui.movieSearch.text(): QMessageBox.about( self, _("Error"), _("Please fill out the search title")) else: self.setCursor(Qt.WaitCursor) try: results = self._main.OSDBServer.SearchMoviesOnIMDB( self.ui.movieSearch.text()) # In case of empty results if not results or not len(results) or "id" not in results[0]: results = [] except: QMessageBox.about( self, _("Error"), _("Error contacting the server. Please try again later")) results = [] self.imdbModel.layoutAboutToBeChanged.emit() self.imdbModel.setImdbResults(results) QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.imdbModel.layoutChanged.emit() self.ui.searchResultsView.resizeRowsToContents() self.setCursor(Qt.ArrowCursor) def updateButtonsIMDB(self): self.ui.searchResultsView.resizeRowsToContents() selected = self.imdbSelectionModel.selection() if selected.count(): self.imdbModel.rowSelected = selected.last().bottomRight().row() self.ui.movieInfoButton.setEnabled(True) self.ui.okButton.setEnabled(True) else: self.imdbModel.rowSelected = None self.ui.movieInfoButton.setEnabled(False) self.ui.okButton.setEnabled(False) @pyqtSlot(QItemSelection, QItemSelection) def onIMDBChangeSelection(self, selected, unselected): self.updateButtonsIMDB() @pyqtSlot() def onMovieInfoButton(self): if self.imdbModel.rowSelected == None: QMessageBox.about( self, _("Error"), _("Please search and select a movie from the list")) else: imdbID = self.imdbModel.getSelectedImdb()["id"] webbrowser.open("http://www.imdb.com/title/tt%s" % imdbID, new=2, autoraise=1) @pyqtSlot() def onOkButton(self): if self.imdbModel.rowSelected == None: QMessageBox.about( self, _("Error"), _("Please search and select a movie from the list")) else: selection = self.imdbModel.getSelectedImdb() self._main.imdbDetected.emit( selection["id"], selection["title"], "search") self.accept() @pyqtSlot() def onCancelButton(self): self.reject()
class ViewAssistMixin(object): selection_changed = pyqtSignal(QItemSelection, QItemSelection) # ... selected (set), deselected (set) selected_maydelete = pyqtSignal(bool, bool) # ... selected # ------------------------------------------------------------------------- # Initialization and setting data (model) # ------------------------------------------------------------------------- def __init__(self, session: Session, modal_dialog_class, readonly: bool = False, **kwargs) -> None: super().__init__(**kwargs) self.session = session self.modal_dialog_class = modal_dialog_class self.readonly = readonly self.selection_model = None def set_model_common(self, model, list_base_class) -> None: if self.selection_model: self.selection_model.selectionChanged.disconnect() list_base_class.setModel(self, model) self.selection_model = QItemSelectionModel(model) self.selection_model.selectionChanged.connect(self._selection_changed) self.setSelectionModel(self.selection_model) # ------------------------------------------------------------------------- # Selection # ------------------------------------------------------------------------- def clear_selection(self) -> None: # log.debug("GenericAttrTableView.clear_selection") if not self.selection_model: return self.selection_model.clearSelection() def get_selected_row_index(self) -> Optional[int]: """Returns an integer or None.""" selected_modelindex = self.get_selected_modelindex() if selected_modelindex is None: return None return selected_modelindex.row() def is_selected(self) -> bool: row_index = self.get_selected_row_index() return row_index is not None def get_selected_object(self) -> Optional[object]: index = self.get_selected_row_index() if index is None: return None model = self.model() if model is None: return None return model.get_object(index) def get_selected_modelindex(self) -> Optional[QModelIndex]: raise NotImplementedError() def go_to(self, row: Optional[int]) -> None: model = self.model() if row is None: # Go to the end. nrows = model.rowCount() if nrows == 0: return row = nrows - 1 modelindex = model.index(row, 0) # second parameter is column self.setCurrentIndex(modelindex) def _selection_changed(self, selected, deselected) -> None: self.selection_changed.emit(selected, deselected) selected_model_indexes = selected.indexes() selected_row_indexes = [mi.row() for mi in selected_model_indexes] is_selected = bool(selected_row_indexes) model = self.model() may_delete = is_selected and all( [model.item_deletable(ri) for ri in selected_row_indexes]) self.selected_maydelete.emit(is_selected, may_delete) def get_n_rows(self) -> int: model = self.model() return model.rowCount() # ------------------------------------------------------------------------- # Add # ------------------------------------------------------------------------- def insert_at_index(self, obj: object, index: int = None, add_to_session: bool = True, flush: bool = True) -> None: # index: None for end, 0 for start model = self.model() model.insert_at_index(obj, index, add_to_session=add_to_session, flush=flush) self.go_to(index) def insert_at_start(self, obj: object, add_to_session: bool = True, flush: bool = True) -> None: self.insert_at_index(obj, 0, add_to_session=add_to_session, flush=flush) def insert_at_end(self, obj: object, add_to_session: bool = True, flush: bool = True) -> None: self.insert_at_index(obj, None, add_to_session=add_to_session, flush=flush) def add_in_nested_transaction(self, new_object: object, at_index: int = None) -> Optional[int]: # at_index: None for end, 0 for start if self.readonly: log.warning("Can't add; readonly") return result = None try: with self.session.begin_nested(): self.session.add(new_object) win = self.modal_dialog_class(self.session, new_object) result = win.edit_in_nested_transaction() if result != QDialog.Accepted: raise EditCancelledException() self.insert_at_index(new_object, at_index, add_to_session=False) return result except EditCancelledException: log.debug("Add operation has been rolled back.") return result # ------------------------------------------------------------------------- # Remove # ------------------------------------------------------------------------- def remove_selected(self, delete_from_session: bool = True) -> None: row_index = self.get_selected_row_index() self.remove_by_index(row_index, delete_from_session=delete_from_session) def remove_by_index(self, row_index: int, delete_from_session: bool = True) -> None: if row_index is None: return model = self.model() model.delete_item(row_index, delete_from_session=delete_from_session) # ------------------------------------------------------------------------- # Move # ------------------------------------------------------------------------- def move_selected_up(self) -> None: row_index = self.get_selected_row_index() if row_index is None or row_index == 0: return model = self.model() model.move_up(row_index) self.go_to(row_index - 1) def move_selected_down(self) -> None: row_index = self.get_selected_row_index() if row_index is None or row_index == self.get_n_rows() - 1: return model = self.model() model.move_down(row_index) self.go_to(row_index + 1) # ------------------------------------------------------------------------- # Edit # ------------------------------------------------------------------------- # noinspection PyUnusedLocal def edit(self, index: QModelIndex, trigger, event) -> bool: if trigger != QAbstractItemView.DoubleClicked: return False self.edit_by_modelindex(index) return False def edit_by_modelindex(self, index: QModelIndex, readonly: bool = None) -> None: if index is None: return if readonly is None: readonly = self.readonly model = self.model() item = model.listdata[index.row()] win = self.modal_dialog_class(self.session, item, readonly=readonly) win.edit_in_nested_transaction() def edit_selected(self, readonly: bool = None) -> None: selected_modelindex = self.get_selected_modelindex() self.edit_by_modelindex(selected_modelindex, readonly=readonly)
class ListModel(QAbstractTableModel): orderChanged = pyqtSignal() elementSelected = pyqtSignal(int) class ColumnID(object): ''' Define how many column the model holds and their type ''' ncols=2 Name=0 Delete=1 def __init__(self, elements=None, parent=None): ''' Common interface for the labelListModel, the boxListModel, and the cropListModel see concrete implementations for details :param elements: :param parent: ''' QAbstractTableModel.__init__(self, parent) if elements is None: elements = [] self._elements = list(elements) self._selectionModel = QItemSelectionModel(self) def onSelectionChanged(selected, deselected): if selected: ind = selected[0].indexes() if len(ind)>0: self.elementSelected.emit(ind[0].row()) self._selectionModel.selectionChanged.connect(onSelectionChanged) self._allowRemove = True self._toolTipSuffixes = {} self.unremovable_rows=[] #rows in this list cannot be removed from the gui, # to add to this list call self.makeRowPermanent(int) # to remove make the self.makeRowRemovable(int) def makeRowPermanent(self, rowIndex): """ The rowindex cannot be removed from gui to remove this index use self.makeRowRemovable """ self.unremovable_rows.append(rowIndex) def makeRowRemovable(self, rowIndex): """ :param rowIndex: is the index for the label of interest in the current gui setting """ self.unremovable_rows.remove(rowIndex) def __len__(self): return len(self._elements) def __getitem__(self, i): return self._elements[i] def selectedRow(self): selected = self._selectionModel.selectedRows() if len(selected) == 1: return selected[0].row() return -1 def selectedIndex(self): row = self.selectedRow() if row >= 0: return self.index(self.selectedRow()) else: return QModelIndex() def rowCount(self, parent=None): return len(self._elements) def columnCount(self, parent): return self.ColumnID.ncols def _getToolTipSuffix(self, row): """ Get the middle column tooltip suffix """ suffix = "; Click to select" if row in self._toolTipSuffixes: suffix = self._toolTipSuffixes[row] return suffix def _setToolTipSuffix(self, row, text): """ Set the middle column tooltip suffix """ self._toolTipSuffixes[row] = text index = self.createIndex(row, 1) self.dataChanged.emit(index, index) class EntryToolTipAdapter(object): """This class can be used to make each row look like a separate widget with its own tooltip. In this case, the "tooltip" is the suffix appended to the tooltip of the middle column. """ def __init__(self, table, row): self._row = row self._table = table def toolTip(self): return self._table._getToolTipSuffix(self._row) def setToolTip(self, text): self._table._setToolTipSuffix(self._row, text) def insertRow(self, position, object, parent=QModelIndex()): self.beginInsertRows(parent, position, position) object.changed.connect(self.modelReset) self._elements.insert(position, object) self.endInsertRows() return True def removeRow(self, position, parent=QModelIndex()): if position in self.unremovable_rows: return False self.beginRemoveRows(parent, position, position) value = self._elements[position] logger.debug("removing row: " + str(value)) self._elements.remove(value) self.endRemoveRows() return True def allowRemove(self, check): #Allow removing of rows. Needed to be able to disallow it #in interactive mode self._allowRemove = check self.dataChanged.emit(self.createIndex(0, self.ColumnID.Delete), self.createIndex(self.rowCount(), self.ColumnID.Delete)) def data(self, index, role): ''' Reimplement, see labelListModel or boxListModel for concrete example :param index: :param role: ''' if role == Qt.EditRole and index.column() == self.ColumnID.Name: name = self._elements[index.row()].name return name elif role == Qt.ToolTipRole and index.column() == self.ColumnID.Delete: s = "Delete {}".format(self._elements[index.row()].name) return s elif role == Qt.ToolTipRole and index.column() == self.ColumnID.Name: suffix = self._getToolTipSuffix(index.row()) s = "{}\nDouble click to rename {}".format( self._elements[index.row()].name, suffix) return s elif role == Qt.DisplayRole and index.column() == self.ColumnID.Name: name = self._elements[index.row()].name return name if role == Qt.DecorationRole and index.column() == self.ColumnID.Delete: if index.row() in self.unremovable_rows: return row = index.row() pixmap = QPixmap(_NPIXELS, _NPIXELS) pixmap.fill(Qt.transparent) painter = QPainter() painter.begin(pixmap) painter.setRenderHint(QPainter.Antialiasing) painter.setBrush(QColor("red")) painter.drawEllipse(1, 1, _NPIXELS - 2, _NPIXELS - 2) pen = QPen(QColor("black")) pen.setWidth(2) painter.setPen(pen) x = _XSTART y = _NPIXELS - x painter.drawLine(x, x, y, y) painter.drawLine(y, x, x, y) painter.end() icon = QIcon(pixmap) return icon def flags(self, index): ''' Reimplement, see labelListModel or boxListModel for concrete example :param index: ''' if index.column() == self.ColumnID.Delete: if self._allowRemove: return Qt.ItemIsEnabled | Qt.ItemIsSelectable else: return Qt.NoItemFlags elif index.column() == self.ColumnID.Name: return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable else: return Qt.NoItemFlags def setData(self, index, value, role=Qt.EditRole): ''' Reimplement, see labelListModel or boxListModel for concrete example :param index: ''' if role == Qt.EditRole and index.column() == self.ColumnID.Name: row = index.row() self._elements[row].name = value self.dataChanged.emit(index, index) return True return False def select(self, row): ''' Reimplement, see labelListModel or boxListModel for concrete example :param row ''' self._selectionModel.clear() self._selectionModel.select(self.index(row, self.ColumnID.Name), QItemSelectionModel.Select) def clearSelectionModel(self): self._selectionModel.clear()
def __init__(self, model, parent=None): QItemSelectionModel.__init__(self, model, parent) self.selectionChanged.connect(self.onSelectionChanged)
def select(self, index, flags=QItemSelectionModel.ClearAndSelect): if isinstance(index, int): index = self.model().index(index) return QItemSelectionModel.select(self, index, flags)
class AccountsManager(ui.manageAccounts.Ui_Dialog, QDialog): """ GUI that handles creation, editing and deletion of accounts. """ def __init__(self, orm): super().__init__() self.setupUi(self) self.orm = orm self.accounts = ListModel() self.accountsView.setModel(self.accounts) self.selection = QItemSelectionModel(self.accounts) self.accountsView.setSelectionModel(self.selection) self.selection.currentRowChanged.connect(self.selection_changed) self.typeBox.addItems(ACCOUNT_TYPES) self.typeBox.currentTextChanged.connect(self.type_changed) self.closedBox.stateChanged.connect(self.closed_changed) self.exBudgetBox.stateChanged.connect(self.budget_changed) self.addAccountButton.clicked.connect(self.add_account) self.deleteAccountButton.clicked.connect(self.delete_account) for acc in self.orm.fetch_accounts(): self.accounts.addItem(acc) def selection_changed(self, curr_index: QModelIndex, prev_index: QModelIndex): """ Updates the information about currently selected account. """ if not curr_index.isValid(): return None # Make sure selection is visible in the view self.selection.setCurrentIndex( curr_index, QItemSelectionModel.SelectCurrent) acc = curr_index.data(role=Qt.UserRole) # Set the type of account self.typeBox.setCurrentText(acc.type) # Set the checkboxes self.closedBox.setChecked(acc.closed) self.exBudgetBox.setChecked(acc.exbudget) def type_changed(self, text: str): """ Changes the type of the account in DB and GUI. """ model_indexes = self.selection.selectedIndexes() if not model_indexes: return None model_index = model_indexes[0] acc = model_index.data(role=Qt.UserRole) # Catch only changes that differ for selected account if acc.type != text: self.orm.update_account_type(acc, text) acc.type = text def closed_changed(self, state: int): """ Changes close status of the account in DB and GUI. """ model_indexes = self.selection.selectedIndexes() if not model_indexes: return None model_index = model_indexes[0] acc = model_index.data(role=Qt.UserRole) # Catch only changes that differ for selected account # acc states in (0,1); Qt.CheckState in (0,1,2) # (0,1,2)//2 -> (0,0,1) state //= 2 if acc.closed != state: self.orm.update_account_status(acc, state) acc.closed = state def budget_changed(self, state: int): """ Changes the budget status of account in DB and GUI. """ model_indexes = self.selection.selectedIndexes() if not model_indexes: return None model_index = model_indexes[0] acc = model_index.data(role=Qt.UserRole) # Catch only changes that differ for selected account # acc states in (0,1); Qt.CheckState in (0,1,2) # (0,1,2)//2 -> (0,0,1) state //= 2 if acc.exbudget != state: self.orm.update_account_budget_status(acc, state) acc.exbudget = state def add_account(self): """ Creates account with default attributes in DB and adds it to GUI. """ name, ok = QInputDialog.getText(self, "Add new account", "Enter the name of the new account:") if ok and name: acc = self.orm.add_account(name) self.accounts.addItem(acc) def delete_account(self): """ Tries to delete the account from DB, if successful deletes it from GUI. """ model_indexes = self.selection.selectedIndexes() if not model_indexes: # the list of accounts is empty return None model_index = model_indexes[0] acc = model_index.data(role=Qt.UserRole) msgBox = QMessageBox() msgBox.setText("Delete the {} account?".format(acc.name)) msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msgBox.setDefaultButton(QMessageBox.Cancel) ret = msgBox.exec() if ret == QMessageBox.Ok: deletion = self.orm.delete_account(acc) if not deletion: show_warning("Can't delete account.") else: self.accounts.removeRow(model_index.row())