class DBViewWindow(QWidget, Ui_DB_View_Form): def __init__(self, database_name): super().__init__() # uic.loadUi('db_view.ui', self) self.setupUi(self) # self.db_name = database_name # # Подключение БД к таблице отображения # # Подключение через QSqlRelationalTableModel # self.db = QSqlDatabase.addDatabase('QSQLITE') # self.db.setDatabaseName(self.db_name) # self.db.open() self.model = QSqlRelationalTableModel(self) self.model.setTable('goods') self.model.setRelation( 5, QSqlRelation('statuses', 'id_status', 'status_name')) self.model.setRelation( 6, QSqlRelation('goods_types', 'id_goods_type', 'goods_type_name')) self.model.setRelation( 7, QSqlRelation('goods_subtypes', 'id_goods_subtype', 'goods_subtype_name')) self.model.setRelation( 8, QSqlRelation('location', 'id_location', 'location_name')) self.model.setRelation( 9, QSqlRelation('responsibles', 'id_responsible', 'FIO')) self.refresh() self.tableView.doubleClicked.connect(self.table_clicked) # self.tableView.clicked.connect() self.refreshBtn.clicked.connect(self.refresh) self.save_all_btn.clicked.connect(self.submitall) def table_clicked(self): row = self.tableView.currentIndex().row() if row != -1: self.tableView.selectRow(row) index = self.tableView.currentIndex() self.edit_form = EditForm(index, self.model) self.edit_form.show() # Предположительно на выходе будет закрываться БД def __exit__(self, exc_type, exc_val, exc_tb): self.db.close() super().__exit__() def refresh(self): self.model.select() self.tableView.setModel(self.model) self.tableView.setItemDelegate(QSqlRelationalDelegate(self.tableView)) def submitall(self): if not self.model.submitAll(): print(self.model.lastError()) else: self.refresh()
class TableModel(): def __init__(self, db): self.model = QSqlRelationalTableModel(db=db) self.model.setTable('balance') self.model.setEditStrategy(QSqlRelationalTableModel.OnFieldChange) self.model.setRelation(1, QSqlRelation('items', 'id', 'name')) self.model.setRelation(2, QSqlRelation('categories', 'id', 'name')) self.model.setRelation(4, QSqlRelation('currencies', 'id', 'name')) self.model.setRelation(5, QSqlRelation('users', 'id', 'full_name')) self.model.setRelation(6, QSqlRelation('places', 'id', 'name')) self.model.setRelation(8, QSqlRelation('measures', 'id', 'short')) self.model.setHeaderData(0, Qt.Horizontal, QtGui.qApp.tr("ID")) self.model.setHeaderData(1, Qt.Horizontal, QtGui.qApp.tr("Item")) self.model.setHeaderData(2, Qt.Horizontal, QtGui.qApp.tr("Category")) self.model.setHeaderData(3, Qt.Horizontal, QtGui.qApp.tr("Cost")) self.model.setHeaderData(4, Qt.Horizontal, QtGui.qApp.tr("Currency")) self.model.setHeaderData(5, Qt.Horizontal, QtGui.qApp.tr("By whom")) self.model.setHeaderData(6, Qt.Horizontal, QtGui.qApp.tr("Where")) self.model.setHeaderData(7, Qt.Horizontal, QtGui.qApp.tr("Qty/Amount")) self.model.setHeaderData(8, Qt.Horizontal, QtGui.qApp.tr("Units")) self.model.setHeaderData(9, Qt.Horizontal, QtGui.qApp.tr("is spending")) self.model.setHeaderData(10, Qt.Horizontal, QtGui.qApp.tr("Note")) self.model.setHeaderData(11, Qt.Horizontal, QtGui.qApp.tr("Date and " "Time")) self.model.removeColumn(12) self.model.removeColumn(13) if not self.model.select(): _log("Table model selection error[%s]: %s" % ( self.model.lastError().type(), self.model.lastError().text() )) def get_model(self): return self.model
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.tableView) # tableView显示属性设置 self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectItems) self.ui.tableView.setSelectionMode(QAbstractItemView.SingleSelection) self.ui.tableView.setAlternatingRowColors(True) self.ui.tableView.verticalHeader().setDefaultSectionSize(22) self.ui.tableView.horizontalHeader().setDefaultSectionSize(100) ## ==============自定义功能函数============ def __getFieldNames(self): ##获取所有字段名称 emptyRec = self.tabModel.record() #获取空记录,只有字段名 self.fldNum = {} #字段名与序号的字典 for i in range(emptyRec.count()): fieldName = emptyRec.fieldName(i) self.fldNum.setdefault(fieldName) self.fldNum[fieldName] = i print(self.fldNum) 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) ## ==========由connectSlotsByName() 自动连接的槽函数================== @pyqtSlot() def on_actOpenDB_triggered(self): dbFilename, flt = QFileDialog.getOpenFileName( self, "选择数据库文件", "", "SQL Lite数据库(*.db *.db3)") if (dbFilename == ''): return #打开数据库 self.DB = QSqlDatabase.addDatabase("QSQLITE") #添加 SQL LITE数据库驱动 self.DB.setDatabaseName(dbFilename) #设置数据库名称 ## DB.setHostName() ## DB.setUserName() ## DB.setPassword() if self.DB.open(): #打开数据库 self.__openTable() #打开数据表 else: QMessageBox.warning(self, "错误", "打开数据库失败") @pyqtSlot() ##保存修改 def on_actSubmit_triggered(self): res = self.tabModel.submitAll() if (res == False): QMessageBox.information( self, "消息", "数据保存错误,错误信息\n" + self.tabModel.lastError().text()) else: self.ui.actSubmit.setEnabled(False) self.ui.actRevert.setEnabled(False) @pyqtSlot() ##取消修改 def on_actRevert_triggered(self): self.tabModel.revertAll() self.ui.actSubmit.setEnabled(False) self.ui.actRevert.setEnabled(False) @pyqtSlot() ##添加记录 def on_actRecAppend_triggered(self): self.tabModel.insertRow(self.tabModel.rowCount(), QModelIndex()) #在末尾添加一个记录 curIndex = self.tabModel.index(self.tabModel.rowCount() - 1, 1) #创建最后一行的ModelIndex self.selModel.clearSelection() #清空选择项 self.selModel.setCurrentIndex( curIndex, QItemSelectionModel.Select) #设置刚插入的行为当前选择行 @pyqtSlot() ##插入记录 def on_actRecInsert_triggered(self): curIndex = self.ui.tableView.currentIndex() #QModelIndex self.tabModel.insertRow(curIndex.row(), QModelIndex()) self.selModel.clearSelection() #清除已有选择 self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select) @pyqtSlot() ##删除记录 def on_actRecDelete_triggered(self): curIndex = self.selModel.currentIndex() #获取当前选择单元格的模型索引 self.tabModel.removeRow(curIndex.row()) #删除最后一行 @pyqtSlot() ##显示字段列表 def on_actFields_triggered(self): emptyRec = self.tabModel.record() #获取空记录,只有字段名 str = '' for i in range(emptyRec.count()): str = str + emptyRec.fieldName(i) + '\n' QMessageBox.information(self, "所有字段名", str) ## =============自定义槽函数=============================== def do_currentChanged(self, current, previous): ##更新actPost和actCancel 的状态 self.ui.actSubmit.setEnabled(self.tabModel.isDirty()) #有未保存修改时可用 self.ui.actRevert.setEnabled(self.tabModel.isDirty())
def __init__(self, parent=None): super().__init__(parent) horizontalLayout = QHBoxLayout() self.dayView = QTableView() self.dayView.setFrameShape(QFrame.Box) self.dayView.horizontalHeader().setStretchLastSection(True) self.dayView.verticalHeader().setVisible(False) horizontalLayout.addWidget(self.dayView) verticalLayout = QVBoxLayout() self.calendarWidget = QCalendarWidget() self.calendarWidget.setMinimumSize(QSize(250, 200)) self.calendarWidget.setMaximumSize(QSize(250, 200)) self.calendarWidget.setMinimumDate(QDate(2017, 1, 1)) self.calendarWidget.setMaximumDate(QDate(2030, 1, 1)) self.calendarWidget.selectionChanged.connect(self.dataChange) self.calendarWidget.setSelectedDate(QDate.currentDate()) verticalLayout.addWidget(self.calendarWidget) titleFV = QLabel('Food View') verticalLayout.addWidget(titleFV) self.filterLine = QLineEdit() self.filterLine.setMaximumSize(QSize(200, 25)) self.filterLine.textChanged.connect(self.filterChange) buttonAdd = QPushButton(QIcon("images/add.png"), '', None) buttonAdd.setMaximumSize(QSize(20, 30)) buttonAdd.clicked.connect(self.addFood) buttonDell = QPushButton(QIcon("images/del.png"), '', None) buttonDell.setMaximumSize(QSize(20, 30)) buttonDell.clicked.connect(self.delFood) lineEditLayout = QHBoxLayout() lineEditLayout.addWidget(self.filterLine) lineEditLayout.addWidget(buttonAdd) lineEditLayout.addWidget(buttonDell) verticalLayout.addLayout(lineEditLayout) self.foodView = QTableView() self.foodView.setMinimumSize(QSize(0, 0)) self.foodView.setMaximumSize(QSize(250, 1000)) self.foodView.verticalHeader().setVisible(False) self.foodView.horizontalHeader().setStretchLastSection(True) verticalLayout.addWidget(self.foodView) horizontalLayout.addLayout(verticalLayout) self.setLayout(horizontalLayout) model_in = QSqlRelationalTableModel() model_in.setEditStrategy(QSqlTableModel.OnFieldChange) model_in.setTable("intake_food") id_food = model_in.fieldIndex("id_food") date = model_in.fieldIndex("food_date") mass = model_in.fieldIndex("mass") # Set model, hide ID column model_in.setRelation(id_food, QSqlRelation("food", "id", "name")) model_in.setHeaderData(id_food, Qt.Horizontal, "Food") model_in.setHeaderData(date, Qt.Horizontal, "Date") model_in.setHeaderData(mass, Qt.Horizontal, "Mass") if not model_in.select(): self.showError(model_in.lastError()) return self.proxyModel_in = QSortFilterProxyModel() self.proxyModel_in.setSourceModel(model_in) self.proxyModel_in.setFilterKeyColumn(2) self.dayView.setItemDelegate(FlipProxyDelegate()) self.dayView.setModel(self.proxyModel_in) self.dayView.setColumnHidden(0, True) self.dayView.setColumnHidden(2, True) self.dayView.setSelectionMode(QAbstractItemView.SingleSelection) self.dayView.setContextMenuPolicy(Qt.CustomContextMenu) self.dayView.customContextMenuRequested.connect(self.ShowContextMenu) # filter day food by calendar widget self.dataChange() self.model_f = QSqlRelationalTableModel() self.model_f.setEditStrategy(QSqlTableModel.OnFieldChange) self.model_f.setTable("food") self.model_f.setHeaderData(1, Qt.Horizontal, "Food") self.model_f.setHeaderData(2, Qt.Horizontal, "Rate") if not self.model_f.select(): self.showError(self.model_f.lastError()) return self.proxyModel_f = QSortFilterProxyModel() self.proxyModel_f.setSourceModel(self.model_f) self.proxyModel_f.setFilterKeyColumn(1) self.foodView.setModel(self.proxyModel_f) self.foodView.setColumnHidden(0, True) self.foodView.setSelectionMode(QAbstractItemView.SingleSelection) self.foodView.setColumnWidth(1, 150) self.foodView.setColumnWidth(2, 90)
class MyWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) horizontalLayout = QHBoxLayout() self.dayView = QTableView() self.dayView.setFrameShape(QFrame.Box) self.dayView.horizontalHeader().setStretchLastSection(True) self.dayView.verticalHeader().setVisible(False) horizontalLayout.addWidget(self.dayView) verticalLayout = QVBoxLayout() self.calendarWidget = QCalendarWidget() self.calendarWidget.setMinimumSize(QSize(250, 200)) self.calendarWidget.setMaximumSize(QSize(250, 200)) self.calendarWidget.setMinimumDate(QDate(2017, 1, 1)) self.calendarWidget.setMaximumDate(QDate(2030, 1, 1)) self.calendarWidget.selectionChanged.connect(self.dataChange) self.calendarWidget.setSelectedDate(QDate.currentDate()) verticalLayout.addWidget(self.calendarWidget) titleFV = QLabel('Food View') verticalLayout.addWidget(titleFV) self.filterLine = QLineEdit() self.filterLine.setMaximumSize(QSize(200, 25)) self.filterLine.textChanged.connect(self.filterChange) buttonAdd = QPushButton(QIcon("images/add.png"), '', None) buttonAdd.setMaximumSize(QSize(20, 30)) buttonAdd.clicked.connect(self.addFood) buttonDell = QPushButton(QIcon("images/del.png"), '', None) buttonDell.setMaximumSize(QSize(20, 30)) buttonDell.clicked.connect(self.delFood) lineEditLayout = QHBoxLayout() lineEditLayout.addWidget(self.filterLine) lineEditLayout.addWidget(buttonAdd) lineEditLayout.addWidget(buttonDell) verticalLayout.addLayout(lineEditLayout) self.foodView = QTableView() self.foodView.setMinimumSize(QSize(0, 0)) self.foodView.setMaximumSize(QSize(250, 1000)) self.foodView.verticalHeader().setVisible(False) self.foodView.horizontalHeader().setStretchLastSection(True) verticalLayout.addWidget(self.foodView) horizontalLayout.addLayout(verticalLayout) self.setLayout(horizontalLayout) model_in = QSqlRelationalTableModel() model_in.setEditStrategy(QSqlTableModel.OnFieldChange) model_in.setTable("intake_food") id_food = model_in.fieldIndex("id_food") date = model_in.fieldIndex("food_date") mass = model_in.fieldIndex("mass") # Set model, hide ID column model_in.setRelation(id_food, QSqlRelation("food", "id", "name")) model_in.setHeaderData(id_food, Qt.Horizontal, "Food") model_in.setHeaderData(date, Qt.Horizontal, "Date") model_in.setHeaderData(mass, Qt.Horizontal, "Mass") if not model_in.select(): self.showError(model_in.lastError()) return self.proxyModel_in = QSortFilterProxyModel() self.proxyModel_in.setSourceModel(model_in) self.proxyModel_in.setFilterKeyColumn(2) self.dayView.setItemDelegate(FlipProxyDelegate()) self.dayView.setModel(self.proxyModel_in) self.dayView.setColumnHidden(0, True) self.dayView.setColumnHidden(2, True) self.dayView.setSelectionMode(QAbstractItemView.SingleSelection) self.dayView.setContextMenuPolicy(Qt.CustomContextMenu) self.dayView.customContextMenuRequested.connect(self.ShowContextMenu) # filter day food by calendar widget self.dataChange() self.model_f = QSqlRelationalTableModel() self.model_f.setEditStrategy(QSqlTableModel.OnFieldChange) self.model_f.setTable("food") self.model_f.setHeaderData(1, Qt.Horizontal, "Food") self.model_f.setHeaderData(2, Qt.Horizontal, "Rate") if not self.model_f.select(): self.showError(self.model_f.lastError()) return self.proxyModel_f = QSortFilterProxyModel() self.proxyModel_f.setSourceModel(self.model_f) self.proxyModel_f.setFilterKeyColumn(1) self.foodView.setModel(self.proxyModel_f) self.foodView.setColumnHidden(0, True) self.foodView.setSelectionMode(QAbstractItemView.SingleSelection) self.foodView.setColumnWidth(1, 150) self.foodView.setColumnWidth(2, 90) def showError(self, err): QMessageBox.critical(self, "Unable to initialize Database", "Error initializing database: " + err.text()) def filterChange(self): regExp = QRegExp(self.filterLine.text(), Qt.CaseInsensitive, QRegExp.FixedString) self.proxyModel_f.setFilterRegExp(regExp) def dataChange(self): date = self.calendarWidget.selectedDate().toString('dd.MM.yyyy') regExp = QRegExp(date, Qt.CaseInsensitive, QRegExp.FixedString) self.proxyModel_in.setFilterRegExp(regExp) def addFood(self): self.model_f.insertRow(self.model_f.rowCount()) def delFood(self): self.model_f.removeRow(self.foodView.currentIndex().row()) self.model_f.select() def resizeEvent(self, event): self.dayView.setColumnWidth(1, self.dayView.width() * 0.7) self.dayView.setColumnWidth(3, self.dayView.width() * 0.2) QWidget.resizeEvent(self, event) def ShowContextMenu(self, pos): contextMenu = QMenu("Context menu", self) action1 = QAction("Add food eaten", self) contextMenu.addAction(action1) contextMenu.exec(self.mapToGlobal(pos))
class QmyMainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setCentralWidget(self.ui.tableView) self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectItems) self.ui.tableView.setSelectionMode(QAbstractItemView.SingleSelection) self.ui.tableView.setAlternatingRowColors(True) self.ui.tableView.verticalHeader().setDefaultSectionSize(22) self.ui.tableView.horizontalHeader().setDefaultSectionSize(100) def __getFieldNames(self): emptyRec = self.tabModel.record() self.fldNum = {} for i in range(emptyRec.count()): fieldName = emptyRec.fieldName(i) self.fldNum.setdefault(fieldName) self.fldNum[fieldName] = i print(self.fldNum) 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) @pyqtSlot() def on_actOpenDB_triggered(self): dbFilename, flt = QFileDialog.getOpenFileName( self, "选择数据库文件", "", "SQL Lite数据库(*.db *.db3)") if (dbFilename == ''): return self.DB = QSqlDatabase.addDatabase("QSQLITE") self.DB.setDatabaseName(dbFilename) if self.DB.open(): self.__openTable() else: QMessageBox.warning(self, "错误", "打开数据库失败了") @pyqtSlot() def on_actSubmit_triggered(self): res = self.tabModel.submitAll() if (res == False): QMessageBox.information( self, "消息", "数据保存错误,错误信息\n" + self.tabModel.lastError().text()) else: self.ui.actSubmit.setEnabled(False) self.ui.actRevert.setEnabled(False) @pyqtSlot() def on_actRevert_triggered(self): self.tabModel.revertAll() self.ui.actSubmit.setEnabled(False) self.ui.actRevert.setEnabled(False) @pyqtSlot() def on_actRecInsert_triggered(self): curIndex = self.ui.tableView.currentIndex() self.tabModel.insertRow(curIndex.row(), QModelIndex()) self.selModel.clearSelection() self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select) @pyqtSlot() def on_actRecDelete_triggered(self): curIndex = self.selModel.currentIndex() self.tabModel.removeRow(curIndex.row()) @pyqtSlot() def on_actFields_triggered(self): emptyRec = self.tabModel.record() str = '' for i in range(emptyRec.count()): str = str + emptyRec.fieldName(i) + '\n' QMessageBox.information(self, "所有字段名", str) def do_currentChanged(self, current, previous): self.ui.actSubmit.setEnabled(self.tabModel.isDirty()) self.ui.actRevert.setEnabled(self.tabModel.isDirty())
class APISSystemTableEditor(QDialog, FORM_CLASS): def __init__(self, dbm, parent=None): """Constructor.""" self.dbm = dbm super(APISSystemTableEditor, self).__init__(parent) self.table = None self.model = None self.insertQuery = None self.updateQuery = None self.deleteQuery = None self.inputDialog = None self.setupUi(self) self.uiEditBtn.setEnabled(False) self.uiRemoveBtn.setEnabled(False) self.rejected.connect(self.onClose) self.setupTable() def setupTable(self): self.uiSystemTableV.setSelectionBehavior(QAbstractItemView.SelectRows) self.uiSystemTableV.setEditTriggers(QAbstractItemView.NoEditTriggers) self.uiSystemTableV.resizeColumnsToContents() self.uiSystemTableV.resizeRowsToContents() self.uiSystemTableV.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) def onSelectionChanged(self): if self.uiSystemTableV.selectionModel().hasSelection(): self.uiEditBtn.setEnabled(True) self.uiRemoveBtn.setEnabled(True) else: self.uiEditBtn.setEnabled(False) self.uiRemoveBtn.setEnabled(False) def loadTable(self, table): # check if table in db if not DbHasTable(self.dbm.db, table): return False self.table = table self.dbm.createTriggerForSystemTable(table) # TODO: if returns FALSE then deactivate editing Capabilites + Wanring self.uiSysTableLbl.setText(self.table) self.model = QSqlRelationalTableModel(self, self.dbm.db) self.model.setTable(table) self.model.select() #rc = self.model.rowCount() while (self.model.canFetchMore()): self.model.fetchMore() #rc = self.model.rowCount() self.uiSystemTableV.setModel(self.model) self.uiSystemTableV.selectionModel().selectionChanged.connect( self.onSelectionChanged) self.onSelectionChanged() # dummyRecord holds field structure! dummyRecord = self.model.record() editors = [] for fIdx in range(dummyRecord.count()): field = dummyRecord.field(fIdx) if field.name() != "ogc_fid": editors.append({ 'name': field.name(), 'type': field.type(), 'lineEdit': QLineEdit(), 'default': None }) # init input dialog self.inputDialog = APISInputDialog(editors, dummyRecord, parent=self) self.uiAddBtn.clicked.connect(self.addRecord) self.uiEditBtn.clicked.connect( self.editRecord ) # in EditMode: load current Value; try to update (but with trigger: only possible to update if not in use!!!) self.uiRemoveBtn.clicked.connect(self.removeRecord) return True def addRecord(self): if self.inputDialog.exec_(): rec = self.inputDialog.getRecord() if not rec.isEmpty(): res = self.model.insertRowIntoTable(rec) if res: self.model.select() self.dbm.dbRequiresUpdate = True else: QMessageBox.warning( self, "DB Fehler", "Der folgende Fehler ist aufgetreten: {}".format( self.model.lastError().text())) else: pass self.inputDialog.resetEditors() def editRecord(self): recIdx = self.uiSystemTableV.selectionModel().currentIndex().row() # Get current Record for index currRec = self.model.record(recIdx) # Set current Record in Dialog self.inputDialog.setEditors(currRec) if self.inputDialog.exec_(): data = self.inputDialog.getData() # QMessageBox.information(None, "edited record", f"{data}") for key in data: currRec.setValue(key, data[key]) if not currRec.isEmpty(): res = self.model.updateRowInTable(recIdx, currRec) if res: self.model.select() self.dbm.dbRequiresUpdate = True else: QMessageBox.warning( self, "DB Fehler", "Der folgende Fehler ist aufgetreten: {}".format( self.model.lastError().text())) self.inputDialog.resetEditors() def removeRecord(self): #Check if one really wants to remove the entry! # Abfrage wirklich löschen header = u"Eintrag löschen" question = u"Möchten Sie den Eintrag wirklich aus der Datenbank löschen?" result = QMessageBox.question(self, header, question, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if result == QMessageBox.Yes: recIdx = self.uiSystemTableV.selectionModel().currentIndex().row() # QMessageBox.information(self, "Information", f"Current Idx {recIdx}") res = self.model.removeRow(recIdx) if res: self.model.select() self.dbm.dbRequiresUpdate = True else: QMessageBox.warning( self, "DB Fehler", "Der folgende Fehler ist aufgetreten: {}".format( self.model.lastError().text())) def onClose(self): ''' Run some actions when the user closes the dialog ''' self.uiAddBtn.clicked.disconnect(self.addRecord) self.uiEditBtn.clicked.disconnect(self.editRecord) self.uiRemoveBtn.clicked.disconnect(self.removeRecord) self.inputDialog.deleteLater()
class APISAdvancedInputDialog(QDialog): def __init__(self, dbm, tableName, showEntriesCombo, modelColumnName=None, excludeEntries=None, parent=None): super(APISAdvancedInputDialog, self).__init__(parent) self.dbm = dbm self.tableName = tableName self.modelColumnName = modelColumnName self.showEntriesCombo = showEntriesCombo self.excludeEntries = excludeEntries self.valueToBeAdded = None self.editors = None self.record = None self.tableExists = False if self.prepairEditorsAndRecord(): self.setupForm() else: pass # something went wrong preping def prepairEditorsAndRecord(self): if not DbHasTable(self.dbm.db, self.tableName): return False self.tableExists = True self.model = QSqlRelationalTableModel(self, self.dbm.db) self.model.setTable(self.tableName) self.model.select() while (self.model.canFetchMore()): self.model.fetchMore() self.record = self.model.record() self.editors = [] for fIdx in range(self.record.count()): field = self.record.field(fIdx) if field.name() != "ogc_fid": self.editors.append({ 'name': field.name(), 'type': field.type(), 'lineEdit': QLineEdit() }) return True def setupForm(self): layout = QFormLayout() if self.showEntriesCombo: self.uiAvailableEntriesCombo = QComboBox() # populate (but exlude if exclude has elements) if self.excludeEntries and len(self.excludeEntries) > 0: self.model.setFilter("{0} NOT IN ({1})".format( self.modelColumnName, ",".join("'{0}'".format(i) for i in self.excludeEntries))) # QMessageBox.information(self, "info", "{0} NOT IN ({1})".format(self.modelColumnName, ",".join("'{0}'".format(i) for i in self.excludeEntries))) # self.model.select() self.model.removeColumn(0) self.setupComboBox(self.uiAvailableEntriesCombo, self.model.fieldIndex(self.modelColumnName)) layout.addRow(self.uiAvailableEntriesCombo) self.uiAddBtn = QPushButton("Hinzufügen") if self.uiAvailableEntriesCombo.count() < 1: self.uiAddBtn.setEnabled(False) self.uiAddBtn.clicked.connect(self.addInputToSelection) layout.addRow(self.uiAddBtn) for editor in self.editors: # QMessageBox.information(self, "info", "{}".format((editor["name"]))) if editor["name"] != "ogc_fid": label = QLabel(editor["name"]) # QMessageBox.information(None, "info", "{}".format(editor["type"])) if editor["type"] == QVariant.Int: intVal = QIntValidator() intVal.setBottom(0) editor['lineEdit'].setValidator(intVal) layout.addRow(label, editor['lineEdit']) editor['lineEdit'].textEdited.connect(self.onTextEdited) self.uiSubmitBtn = QPushButton("Speichern") self.uiSubmitBtn.setEnabled(False) self.uiSubmitBtn.clicked.connect(self.saveInputAsQSqlRecord) layout.addRow(self.uiSubmitBtn) self.setLayout(layout) self.setWindowTitle("APIS Input Dialog") self.adjustSize() def onTextEdited(self, text): for editor in self.editors: if len(editor['lineEdit'].text().replace(" ", "")) == 0: self.uiSubmitBtn.setEnabled(False) return self.uiSubmitBtn.setEnabled(True) def addInputToSelection(self): self.setValueToBeAdded(self.uiAvailableEntriesCombo.currentText()) self.accept() def setValueToBeAdded(self, value): self.valueToBeAdded = value def getValueToBeAdded(self): return self.valueToBeAdded def saveInputAsQSqlRecord(self): for editor in self.editors: self.record.setValue(editor["name"], editor['lineEdit'].text()) if not self.record.isEmpty(): result = self.model.insertRowIntoTable(self.record) if result: self.setValueToBeAdded( self.record.field(self.modelColumnName).value()) self.accept() else: QMessageBox.warning( self, "DB Fehler", "Der folgende Feheler ist aufgetreten: {}".format( self.model.lastError().text())) self.reject() else: self.reject() def setupComboBox(self, editor, modelColumn): tv = QTableView() editor.setView(tv) tv.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) tv.setSelectionMode(QAbstractItemView.SingleSelection) tv.setSelectionBehavior(QAbstractItemView.SelectRows) tv.setAutoScroll(False) editor.setModel(self.model) editor.setModelColumn(modelColumn) editor.setInsertPolicy(QComboBox.NoInsert) tv.resizeColumnsToContents() tv.resizeRowsToContents() tv.verticalHeader().setVisible(False) tv.horizontalHeader().setVisible(True) #tv.setMinimumWidth(tv.horizontalHeader().length()) tv.horizontalHeader().setStretchLastSection(True) #tv.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) tv.resizeColumnsToContents() scroll = 0 if editor.count() <= editor.maxVisibleItems( ) else QApplication.style().pixelMetric(QStyle.PM_ScrollBarExtent) tv.setMinimumWidth(tv.horizontalHeader().length() + scroll)