def setupModel(self): u"""Définit et configure le modèle sous-jacent à la table""" self._modele = QSqlTableModel(self) self._modele.setTable("intervenant") self._modele.setHeaderData(1, Qt.Horizontal, "Nom") self._modele.setHeaderData(2, Qt.Horizontal, u"Téléphone") self._modele.setHeaderData(3, Qt.Horizontal, "Email") self._modele.setEditStrategy(QSqlTableModel.OnFieldChange) self._modele.select() self._ui.tv.setModel(self._modele)
def setup_model(self): db = Db_Instance("oform_product").get_instance() if not db.open(): self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n" "Banco de dados indisponível".decode("utf-8")) QMessageBox.critical(self, "Seareiros - Vendas do Bazar", message) else: # product order self._model = QSqlTableModel(self, db=db) self._model.setTable("order_request") # product order items self._items_model = QSqlTableModel(self, db=db) self._items_model.setTable("product_order_item")
def setup_model(self): db = Db_Instance("oform_book").get_instance() if not db.open(): self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n""Banco de dados indisponível".decode('utf-8')) QMessageBox.critical(self, "Seareiros - Livraria", message) else: # book order self._model = QSqlTableModel(self, db=db) self._model.setTable("order_request") # book order items self._items_model = QSqlTableModel(self, db=db) self._items_model.setTable("book_order_item")
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) database = QSqlDatabase.addDatabase('QSQLITE') database.setDatabaseName('astatsscraper.db') # Better lookup logic needed if not database.open(): print('Error opening database!') model = QSqlTableModel(db=database) model.setTable('steam_apps') table = QTableView() table.setEditTriggers(QAbstractItemView.NoEditTriggers) table.setModel(model) self.setCentralWidget(table) table.show()
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) database = QSqlDatabase.addDatabase('QSQLITE') database.setDatabaseName( 'astatsscraper.db') # Better lookup logic needed if not database.open(): print('Error opening database!') model = QSqlTableModel(db=database) model.setTable('steam_apps') table = QTableView() table.setEditTriggers(QAbstractItemView.NoEditTriggers) table.setModel(model) self.setCentralWidget(table) table.show()
class TableController(object): def __init__(self,tabHost,objectType,objectName,model): self.view=TableView(tabHost) self.model=model self.name=objectName self.type=objectType self._mapdata() self.wireUp() def _mapdata(self): assert self.model.isDBLoaded() self.datamodel=QSqlTableModel(self.view,self.model.db) self.datamodel.setTable(self.name) self.refresh() def wireUp(self): self.datamodel.setEditStrategy(QSqlTableModel.OnManualSubmit) self.view.ui.tableView.setModel(self.datamodel) self.view.ui.tableView.show() if self.type==self.model.ModelArea.TABLES: ##make widget read-write self.view.ui.tableView.setEditTriggers(QAbstractItemView.DoubleClicked | QAbstractItemView.SelectedClicked) self.datamodel.setEditStrategy(QSqlTableModel.OnRowChange) #TODO: track edits for safe saving def refresh(self): self.datamodel.select()
def setup_model(self): db = Db_Instance("edit_book").get_instance() if not db.open(): self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n""Banco de dados indisponível".decode('utf-8')) QMessageBox.critical(self, unicode("Seareiros - Edição de Livro".decode('utf-8')), message) else: # book self._model = QSqlRelationalTableModel(self, db=db) self._model.setTable("book") self._model.setFilter("id = " + str(self._record_id)) # self._model.setRelation(self.column["author"], QSqlRelation("author", "id", "name")) # self._model.setRelation(self.column["s_author"], QSqlRelation("s_author", "id", "name")) # self._model.setRelation(self.column["publisher"], QSqlRelation("publisher", "id", "name")) self._model.select() self._record = self._model.record(0) # models for setting up qcompleters: # book_in_subject self._book_in_subj_model = QSqlTableModel(self, db=db) self._book_in_subj_model.setTable("book_in_subject") # subject self._subject_model = QSqlTableModel(self, db=db) self._subject_model.setTable("subject") self._subject_model.select() # author self._author_model = QSqlTableModel(self, db=db) self._author_model.setTable("author") self._author_model.select() # s_author self._s_author_model = QSqlTableModel(self, db=db) self._s_author_model.setTable("s_author") self._s_author_model.select() # publisher self._publisher_model = QSqlTableModel(self, db=db) self._publisher_model.setTable("publisher") self._publisher_model.select() # retrieving current subjects, should probably place this elsewhere but it's related to models self._subject_records = [] sql_statement = """SELECT id, name FROM subject s, book_in_subject b_s WHERE s.id = b_s.subject_id AND b_s.book_id = %s """ % str(self._record_id) read_only_subject_model = QSqlQueryModel() read_only_subject_model.setQuery(sql_statement, db) # checking query validity if not read_only_subject_model.lastError().isValid(): self._subj_records = iterate_model(read_only_subject_model)
def setup_model(self): db = Db_Instance("form_book").get_instance() if not db.open(): self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n" "Banco de dados indisponível".decode("utf-8")) QMessageBox.critical(self, "Seareiros - Cadastro de Livro", message) else: # book self._model = QSqlTableModel(self, db=db) self._model.setTable("book") # subject self._subject_model = QSqlTableModel(self, db=db) self._subject_model.setTable("subject") self._subject_model.select() # author self._author_model = QSqlTableModel(self, db=db) self._author_model.setTable("author") self._author_model.select() # sauthor self._s_author_model = QSqlTableModel(self, db=db) self._s_author_model.setTable("s_author") self._s_author_model.select() # publisher self._publisher_model = QSqlTableModel(self, db=db) self._publisher_model.setTable("publisher") self._publisher_model.select() # book subjects self._book_in_subj_model = QSqlTableModel(self, db=db) self._book_in_subj_model.setTable("book_in_subject")
class ProductOrderForm(QScrollArea, Ui_ProductOForm): """ Interface for ordering products """ column = {"associate": 1, "obs": 3, "total": 4, "paid": 5, "type": 7} def __init__(self, parent=None): super(ProductOrderForm, self).__init__(parent) self.setupUi(self) # had to subclass this spinbox to support return grabbing self.edQuantity = ReturnKeySpinBox(self) self.edQuantityHolder.addWidget(self.edQuantity) self._access = statics.access_level # for currency formatting self._locale = QLocale() # had to hardcode these, wouldn't work otherwise: self.contentsLayout.setAlignment(self.groupBox, QtCore.Qt.AlignTop) self.contentsLayout.setAlignment(self.groupBox_2, QtCore.Qt.AlignTop) self.contentsLayout.setAlignment(self.groupBox_3, QtCore.Qt.AlignTop) self.contentsLayout.setAlignment(self.groupBox_4, QtCore.Qt.AlignTop) self.log = logging.getLogger("ProductOForm") self.setup_model() self.setup_fields() # associate present flag self._associate_id = None # product internals self._product_list = [] self._total = 0.0 # flag to indicate whether there were changes to the fields self._dirty = False def is_dirty(self): return self._dirty def setup_model(self): db = Db_Instance("oform_product").get_instance() if not db.open(): self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n" "Banco de dados indisponível".decode("utf-8")) QMessageBox.critical(self, "Seareiros - Vendas do Bazar", message) else: # product order self._model = QSqlTableModel(self, db=db) self._model.setTable("order_request") # product order items self._items_model = QSqlTableModel(self, db=db) self._items_model.setTable("product_order_item") def setup_fields(self): """ setting up validators and stuff """ # validators self.edProductName.setValidator(UppercaseValidator()) self.edPrice.setValidator(CurrencyValidator(self.edPrice)) # hiding associate frame and clean button self.frameAssociate.setVisible(False) self.btnCleanAssociate.setVisible(False) # connecting return key to tab for lineEdit in self.findChildren(QLineEdit): # qspinbox has a C++ originated qlineedit "hidden" in it, we don't wanna mess with that if lineEdit.objectName() != "qt_spinbox_lineedit": lineEdit.returnPressed.connect(lineEdit.focusNextChild) # detect changes on line edits lineEdit.textChanged.connect(self.check_changes) self.edQuantity.setMinimum(1) self.edQuantity.setMaximum(2000) self.edQuantity.setValue(1) # fixing tab order self.setTabOrder(self.edPrice, self.edQuantity) self.setTabOrder(self.edQuantity, self.btnAddProduct) def check_changes(self, txt): if txt != "": self._dirty = True def submit_data(self): # I should block empty orders I guess if len(self._product_list) == 0: message = unicode( "Venda vazia!\n\n" "" "É necessário adicionar um produto antes de concluir uma venda".decode("utf-8") ) QMessageBox.critical(self, "Seareiros - Vendas do Bazar", message) self.edProductName.setFocus() return False data = self.extract_input() # filling a product order self._model.insertRow(0) for key, val in data.items(): self._model.setData(self._model.index(0, self.column[key]), val) order_id = submit_and_get_id(self, self._model, self.log) if order_id: # order creation success, placing items error = False for item in self._product_list: product_name = item[0] product_price = item[1] product_quantity = item[2] self._items_model.insertRow(0) self._items_model.setData(self._items_model.index(0, 1), order_id) self._items_model.setData(self._items_model.index(0, 2), product_name) self._items_model.setData(self._items_model.index(0, 3), product_price) self._items_model.setData(self._items_model.index(0, 4), product_quantity) ok = self._items_model.submitAll() if not ok: error = True break if error: self.log.error(self._items_model.lastError().text()) message = unicode( "Erro\n\n" "Venda registrada e contabilizada, porém ocorreu um problema e" " não será possível visualizar seus itens.".decode("utf-8") ) QMessageBox.warning(self, "Seareiros - Vendas do Bazar", message) return False else: # all went fine # retrieving some brief info of the order to display at the main window if "associate" in data: desc = "Venda do bazar no valor de R$ %s para %s" % ( self._locale.toString(data["total"], "f", 2).replace(".", ""), self.lblNickname.text(), ) else: desc = "Venda do bazar no valor de R$ %s" % self._locale.toString(data["total"], "f", 2).replace( ".", "" ) if not log_to_history(self._model.database(), "venda_bazar", order_id, desc): self.log.error(self._model.lastError().text()) message = unicode("Sucesso!\n\n" "Venda concluída.".decode("utf-8")) QMessageBox.information(self, "Seareiros - Vendas do Bazar", message) return True # failed to insert a row return False def clear(self): """ Globally cleans this form """ self._dirty = False for lineEdit in self.findChildren(QLineEdit): lineEdit.clear() # product # edProduct is a QLineEdit so... already clean self.clear_table() self.lblTotal.setText("0,00") self.edQuantity.setValue(1) # associate self.clear_associate() self.edProductName.setFocus() def clear_associate(self): # resets associate frame self.lblName.clear() self.lblNickname.clear() self._associate_id = None self.frameAssociate.setVisible(False) self.btnCleanAssociate.setVisible(False) # can't allow an order to be paid later without an associate to relate to self.rdNotPaid.setEnabled(False) self.rdPaid.setChecked(True) @QtCore.Slot() def on_btnAddProduct_clicked(self): txt = self.edProductName.text() price = self._locale.toDouble(self.edPrice.text())[0] quantity = self.edQuantity.value() if txt != "": data = [txt, price, quantity] self.add_product(data) self.update_total(price * quantity) self.refresh_tableProducts() # cleaning product related input self.edProductName.clear() self.edPrice.setText("0,00") self.edQuantity.setValue(1) self.edProductName.setFocus() @QtCore.Slot() def on_btnSelectAssociate_clicked(self): associate_dialog = AssociateSelectDialog() if associate_dialog.exec_() == QDialog.Accepted: record = associate_dialog.get_record() self._associate_id = record.value("id") self.set_associate_info(record.value("fullname"), record.value("nickname")) self.frameAssociate.setVisible(True) self.btnCleanAssociate.setVisible(True) # a registered associate can pay later self.rdNotPaid.setEnabled(True) self.edProductName.setFocus() def set_associate_info(self, fullname, nickname): self.lblName.setText(fullname) self.lblNickname.setText(nickname) @QtCore.Slot() def on_btnCleanAssociate_clicked(self): self.clear_associate() def update_total(self, price, add=True): if add: self._total += price else: self._total -= price txt = self._locale.toString(self._total, "f", 2).replace(".", "") if txt == "0": txt = txt.replace(txt, "0,00") self.lblTotal.setText(txt) @QtCore.Slot() def on_btnCleanProducts_clicked(self): self.clear_table() self._total = 0.0 self.update_total(0.0) self.edPrice.setText("0,00") self.edQuantity.setValue(1) self.edProductName.clear() self.edProductName.setFocus() def clear_table(self): self._product_list = [] self.tableProducts.clear() self.refresh_tableProducts() def add_product(self, data): """ adds a product to the list then sort it """ self._product_list.append(data) # sorts by name self._product_list.sort(key=operator.itemgetter(0)) def refresh_tableProducts(self): if len(self._product_list) > 0: self.tableProducts.setColumnCount(len(self._product_list[0]) + 1) col_labels = ["Produto", unicode("Preço (R$)".decode("utf-8")), "Qtd", ""] self.tableProducts.setHorizontalHeaderLabels(col_labels) else: self.tableProducts.setColumnCount(0) self.tableProducts.setRowCount(len(self._product_list)) for i, row in enumerate(self._product_list): for j, col in enumerate(row): if j == 1: # product price item = QTableWidgetItem(self._locale.toString(col, "f", 2).replace(".", "")) elif j == 2: # product quantity item = QTableWidgetItem(str(col)) else: item = QTableWidgetItem(col) self.tableProducts.setItem(i, j, item) # icon to remove rows individually remove_icon = QIcon(":icons/conn_failed.png") remove_btn = QPushButton(remove_icon, "") remove_btn.clicked.connect(partial(self.remove_product, product=row)) self.tableProducts.setCellWidget(i, len(row), remove_btn) self.tableProducts.resizeColumnsToContents() self.tableProducts.horizontalHeader().setResizeMode(0, QHeaderView.Stretch) def remove_product(self, product): # remove a row based on its value subtract_value = product[1] * product[2] self._product_list.remove(product) self.refresh_tableProducts() self.update_total(subtract_value, add=False) def extract_input(self): data = {} if self._associate_id: data["associate"] = self._associate_id data["obs"] = self.edObs.toPlainText() data["total"] = self._total if self.rdPaid.isChecked(): data["paid"] = True else: data["paid"] = False data["type"] = constants.ORDER_PRODUCT return data
def _mapdata(self): assert self.model.isDBLoaded() self.datamodel=QSqlTableModel(self.view,self.model.db) self.datamodel.setTable(self.name) self.refresh()
def InitTable(self): """Funzione che accede al database ed imposta il data model""" db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(self.myWidget.txtPercorso.text()) db.open() model = QSqlTableModel() model.setTable("contatti") model.setEditStrategy(QSqlTableModel.OnManualSubmit) model.select() model.setHeaderData(0, QtCore.Qt.Horizontal, "Nome") model.setHeaderData(1, QtCore.Qt.Horizontal, "Cognome") model.setHeaderData(2, QtCore.Qt.Horizontal, "Telefono") self.tableModel = model self.myWidget.lstRubrica.setModel(model)
class BookOrderForm(QScrollArea, Ui_BookOForm): """ Interface for ordering books """ column = { 'associate':1, 'obs':3, 'total':4, 'paid':5, 'type':7 } def __init__(self, parent=None): super(BookOrderForm, self).__init__(parent) self.setupUi(self) self._access = statics.access_level # for currency formatting self._locale = QLocale() # had to hardcode these, wouldn't work otherwise: self.contentsLayout.setAlignment(self.groupBox, QtCore.Qt.AlignTop) self.contentsLayout.setAlignment(self.groupBox_2, QtCore.Qt.AlignTop) self.contentsLayout.setAlignment(self.groupBox_3, QtCore.Qt.AlignTop) self.contentsLayout.setAlignment(self.groupBox_4, QtCore.Qt.AlignTop) self.log = logging.getLogger('BookOForm') self.setup_model() self.setup_fields() # associate present flag self._associate_id = None # book internals self._book_list = [] self._total = 0.0 # flag to indicate whether there were changes to the fields self._dirty = False def is_dirty(self): return self._dirty def setup_model(self): db = Db_Instance("oform_book").get_instance() if not db.open(): self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n""Banco de dados indisponível".decode('utf-8')) QMessageBox.critical(self, "Seareiros - Livraria", message) else: # book order self._model = QSqlTableModel(self, db=db) self._model.setTable("order_request") # book order items self._items_model = QSqlTableModel(self, db=db) self._items_model.setTable("book_order_item") def setup_fields(self): """ setting up validators and stuff """ # validators self.edBarcode.setValidator(NumericValidator()) # hiding associate frame and clean button self.frameAssociate.setVisible(False) self.btnCleanAssociate.setVisible(False) # detect changes on edBarcode for dirtiness and completion self.edBarcode.textChanged.connect(self.check_changes) self.edBarcode.textChanged.connect(self.check_barcode) def check_changes(self, txt): if txt != '': self._dirty = True def check_barcode(self, txt): if len(txt) == self.edBarcode.maxLength(): db = Db_Instance("obook_barcode_search").get_instance() try: if db.open(): query = QSqlQuery(db) query.prepare("SELECT * FROM book WHERE barcode = :barcode") query.bindValue(":barcode", txt) query.exec_() if query.next(): self.add_book_from_record(query.record()) self.edBarcode.clear() else: raise RecordNotFoundException else: raise DbUnavailableException except RecordNotFoundException: message = unicode("Código de barra inválido!\n\n""" "O código informado não corresponde a nenhum livro cadastrado".decode('utf-8')) QMessageBox.critical(self, "Seareiros - Livraria", message) except DbUnavailableException: self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n""Banco de dados indisponível".decode('utf-8')) QMessageBox.critical(self, "Seareiros - Livraria", message) self.edBarcode.setFocus() def submit_data(self): if len(self._book_list) == 0: message = unicode("Venda vazia!\n\n""" "É necessário adicionar um livro antes de concluir uma venda".decode('utf-8')) QMessageBox.critical(self, "Seareiros - Livraria", message) self.edBarcode.setFocus() return False data = self.extract_input() # filling a book order self._model.insertRow(0) for key,val in data.items(): self._model.setData(self._model.index(0, self.column[key]), val) order_id = submit_and_get_id(self, self._model, self.log) if order_id: # order creation success, placing items error = False for item in self._book_list: book_id = item[0] book_quantity = item[3] self._items_model.insertRow(0) self._items_model.setData(self._items_model.index(0,1), order_id) self._items_model.setData(self._items_model.index(0,2), book_id) self._items_model.setData(self._items_model.index(0,3), book_quantity) ok = self._items_model.submitAll() if not ok: error = True break if error: self.log.error(self._items_model.lastError().text()) message = unicode("Erro\n\n""Venda registrada e contabilizada, porém ocorreu um problema e" " não será possível visualizar seus itens.".decode('utf-8')) QMessageBox.warning(self, "Seareiros - Livraria", message) return False else: # all went fine # retrieving some brief info of the order to display at the main window if 'associate' in data: desc = "Venda da livraria no valor de R$ %s para %s" % \ (self._locale.toString(data['total'], 'f', 2).replace('.',''), self.lblNickname.text()) else: desc = "Venda da livraria no valor de R$ %s" % self._locale.toString(data['total'], 'f', 2).replace('.','') if not log_to_history(self._model.database(), "venda_livraria", order_id, desc): self.log.error(self._model.lastError().text()) message = unicode("Sucesso!\n\n""Venda concluída.".decode('utf-8')) QMessageBox.information(self, "Seareiros - Livraria", message) return True # failed to insert a row return False def clear(self): """ Globally cleans this form """ self._dirty = False for lineEdit in self.findChildren(QLineEdit): lineEdit.clear() # book self.clear_table() self.lblTotal.setText("0,00") # associate self.clear_associate() self.edBarcode.setFocus() def clear_associate(self): # resets associate frame self.lblName.clear() self.lblNickname.clear() self._associate_id = None self.frameAssociate.setVisible(False) self.btnCleanAssociate.setVisible(False) # can't allow an order to be paid later without an associate to relate to self.rdNotPaid.setEnabled(False) self.rdPaid.setChecked(True) @QtCore.Slot() def on_btnSelectAssociate_clicked(self): associate_dialog = AssociateSelectDialog() if associate_dialog.exec_() == QDialog.Accepted: record = associate_dialog.get_record() self._associate_id = record.value("id") self.set_associate_info(record.value("fullname"), record.value("nickname")) self.frameAssociate.setVisible(True) self.btnCleanAssociate.setVisible(True) # a registered associate can pay later self.rdNotPaid.setEnabled(True) self.edBarcode.setFocus() @QtCore.Slot() def on_btnSelectBook_clicked(self): book_dialog = BookSelectDialog() if book_dialog.exec_() == QDialog.Accepted: record = book_dialog.get_record() self.add_book_from_record(record) def add_book_from_record(self, record): book_id = record.value("id") book_title = record.value("title") book_price = record.value("price") book_quantity = 1 book_stock = record.value("stock") data = [book_id, book_title, book_price, book_quantity, book_stock] try: self.add_book(data) self.refresh_tableBooks() self.edBarcode.clear() self.edBarcode.setFocus() except StockOverflowException: message = unicode("Estoque Insuficiente!\n\n""A quantidade do item excedeu o estoque".decode('utf-8')) QMessageBox.critical(self, "Seareiros - Livraria", message) def set_associate_info(self, fullname, nickname): self.lblName.setText(fullname) self.lblNickname.setText(nickname) @QtCore.Slot() def on_btnCleanAssociate_clicked(self): self.clear_associate() def update_total(self, price, add=True): if add: self._total += price else: self._total -= price txt = self._locale.toString(self._total, 'f', 2).replace('.','') if txt == '0': txt = txt.replace(txt, "0,00") self.lblTotal.setText(txt) @QtCore.Slot() def on_btnCleanBooks_clicked(self): self.clear_table() self._total = 0.0 self.update_total(0.0) self.edBarcode.clear() self.edBarcode.setFocus() def clear_table(self): self._book_list = [] self.tableBooks.clear() self.refresh_tableBooks() def add_book(self, data): """ adds a book to the list then sort it """ # checking for duplicate dup_index = [i for i,x in enumerate(self._book_list) if x[0] == data[0]] if not dup_index: # not a duplicate self._book_list.append(data) else: # duplicate idx = dup_index[0] # increment quantity new_quantity = self._book_list[idx][3] + 1 stock = self._book_list[idx][4] if new_quantity > stock: raise StockOverflowException else: self._book_list[idx][3] += 1 self.update_total(data[2], add=True) # sorts by title self._book_list.sort(key=operator.itemgetter(1)) def refresh_tableBooks(self): if len(self._book_list) > 0: self.tableBooks.setColumnCount(len(self._book_list[0])-1) col_labels = ["Livro", unicode("Preço (R$)".decode('utf-8')), "Qtd", ""] self.tableBooks.setHorizontalHeaderLabels(col_labels) else: self.tableBooks.setColumnCount(0) self.tableBooks.setRowCount(len(self._book_list)) for i, row in enumerate(self._book_list): for j, col in enumerate(row): if j == 1: # title item = QTableWidgetItem(col) elif j == 2: # price item = QTableWidgetItem(self._locale.toString(col, 'f', 2).replace('.','')) elif j == 3: # quantity edQuantity = ReturnKeySpinBox(self) edQuantity.setMinimum(1) edQuantity.setMaximum(row[4]) edQuantity.setValue(col) edQuantity.valueChanged.connect(partial(self.update_quantity, book=row)) self.tableBooks.setCellWidget(i, j-1, edQuantity) if j in [1,2]: # ignoring id self.tableBooks.setItem(i, j-1, item) # remove button on last column remove_icon = QIcon(":icons/conn_failed.png") remove_btn = QPushButton(remove_icon, "") remove_btn.clicked.connect(partial(self.remove_book, book=row)) self.tableBooks.setCellWidget(i, len(row)-2, remove_btn) self.tableBooks.resizeColumnsToContents() self.tableBooks.horizontalHeader().setResizeMode(0, QHeaderView.Stretch) def remove_book(self, book): # remove a row based on its value subtract_value = book[2] * book[3] self._book_list.remove(book) self.refresh_tableBooks() self.update_total(subtract_value, add=False) def update_quantity(self, i, book): new_value = i old_value = book[3] if old_value == new_value: # this happens sometimes when refreshing the table return price = book[1] index = self._book_list.index(book) book[3] = new_value self._book_list[index] = book if new_value > old_value: # incremented self.update_total((new_value - old_value)*book[2], add=True) elif new_value < old_value: # decremented self.update_total((old_value - new_value)*book[2], add=False) def extract_input(self): data = {} if self._associate_id: data['associate'] = self._associate_id data['obs'] = self.edObs.toPlainText() data['total'] = self._total if self.rdPaid.isChecked(): data['paid'] = True else: data['paid'] = False data['type'] = constants.ORDER_BOOK return data
class BookEditForm(QScrollArea, Ui_BookForm): """ Interface for book edit """ column = { 'id':0, 'barcode':1, 'title':2, 'author':3, 's_author':4, 'publisher':5, 'year':6, 'price':7, 'description':8, 'stock':9, 'image':10, 'availability':11 } IMG_SIZE = (150, 150) def __init__(self, record_id, parent=None): super(BookEditForm, self).__init__(parent) self.setupUi(self) # had to subclass this spinbox to support return grabbing self.edYear = ReturnKeySpinBox(self) self.edYearHolder.addWidget(self.edYear) # configuring id's for radio group self.radioAvailability.setId(self.rdSell,0) self.radioAvailability.setId(self.rdRent,1) self.radioAvailability.setId(self.rdInactive,2) # overlaying a clean button over the image (couldn't do it in designer) self.btnCleanImage = QPushButton() self.btnCleanImage.setIcon(QIcon(":icons/clean.png")) self.btnCleanImage.setFixedWidth(35) self.btnCleanImage.clicked.connect(self.clear_image) self.btnCleanImage.setVisible(False) clean_img_layout = QVBoxLayout(self.edImage) clean_img_layout.addWidget(self.btnCleanImage) clean_img_layout.setAlignment(Qt.AlignTop | Qt.AlignLeft) clean_img_layout.setContentsMargins(2,2,0,0) self._access = statics.access_level # for currency formatting self._locale = QLocale() self._record_id = record_id # had to hardcode these, wouldn't work otherwise: self.contentsLayout.setAlignment(self.groupBox, QtCore.Qt.AlignTop) self.contentsLayout.setAlignment(self.groupBox_2, QtCore.Qt.AlignTop) self.log = logging.getLogger('BookEditForm') self._subject_list = [] self._removed_subjects = [] self._added_subjects = [] self.setup_model() self.fill_form() self.setup_fields() self._old_data = self.extract_input(text_only=True) # flag to indicate whether there were changes to the fields self._dirty = False # user did input an image self._image_set = False # image changed during edit self._image_changed = False def is_dirty(self): return self._dirty def setup_fields(self): """ setting up validators and stuff """ # validators # forcing uppercasing on these fields self.edTitle.setValidator(UppercaseValidator()) self.edAuthor.setValidator(UppercaseValidator()) self.edSAuthor.setValidator(UppercaseValidator()) self.edPublisher.setValidator(UppercaseValidator()) self.edPrice.setValidator(CurrencyValidator(self.edPrice)) self.edBarcode.setValidator(NumericValidator()) self.edYear.setMinimum(1900) self.edYear.setMaximum(date.today().year) self.edYear.setValue(date.today().year) # fixing tab order self.setTabOrder(self.edPublisher, self.edYear) self.setTabOrder(self.edYear, self.edPrice) # connecting return key to tab lineEditList = self.findChildren(QLineEdit) for lineEdit in lineEditList: # had some problem with C++ originated objects if lineEdit.objectName() not in ['qt_spinbox_lineedit', 'edSubject']: lineEdit.returnPressed.connect(lineEdit.focusNextChild) # detect changes on line edits lineEdit.textChanged.connect(self.check_changes) # different behaviour for these self.edBarcode.textChanged.connect(self.check_barcode) self.edSubject.returnPressed.connect(self.on_btnAddSubject_clicked) # completers config_completer(self.edSubject, self._subject_model, "name") config_completer(self.edAuthor, self._author_model, "name") config_completer(self.edSAuthor, self._s_author_model, "name") config_completer(self.edPublisher, self._publisher_model, "name") # making image clickable clickable(self.edImage).connect(self.handle_image) def fill_form(self): # retrieving book info self.edBarcode.setText(self._record.value("barcode")) self.edTitle.setText(self._record.value("title")) self.edYear.setValue(self._record.value("year")) self.edDescription.setPlainText(self._record.value("description")) self.radioAvailability.button(self._record.value("availability")).setChecked(True) # retrieving image ba = QByteArray(self._record.value("image")) if ba: self._image_set = True img = qbytearray_to_qimage(ba) self.set_image(img, clean_visible=True) # currency # TODO: ARRUMAR self.edPrice.setText(self._locale.toString(self._record.value("price"), 'f', 2).replace('.','')) # qcompleter fields self.edAuthor.setText(self._get_name_from_id("author", self._record.value("author_id"))) self.edSAuthor.setText(self._get_name_from_id("s_author", self._record.value("s_author_id"))) self.edPublisher.setText(self._get_name_from_id("publisher", self._record.value("publisher_id"))) # retrieving subjects for subj_record in self._subj_records: self.add_subject([subj_record.value("id"),subj_record.value("name")]) # clearing changes self._added_subjects[:] = [] self.refresh_tableSubjects() def clear_image(self): img = QImage(":icons/no_image.png") self.set_image(img, clean_visible=False) if self._image_set: self._image_set = False self._image_changed = True def handle_image(self): image_path = QFileDialog.getOpenFileName(self, "Escolha uma imagem", os.getenv("HOME"), "Imagens (*.png, *.jpg *.bmp)")[0] if os.path.exists(image_path): self.set_image(QImage(image_path), clean_visible=True) self._image_set = True self._image_changed = True def set_image(self, img, clean_visible=False): pix = QPixmap.fromImage(img) pix = pix.scaled(self.IMG_SIZE[0], self.IMG_SIZE[1], Qt.KeepAspectRatio) self.edImage.setPixmap(pix) self.edImage.setScaledContents(True) self.btnCleanImage.setVisible(clean_visible) def check_changes(self, txt): # getting sender info sender = self.sender().objectName().split('ed')[1].lower() if sender != 'subject' and self._old_data[sender] != txt: self._dirty = True def check_barcode(self, txt): if len(txt) == self.edBarcode.maxLength(): self.edBarcode.focusNextChild() def extract_input(self, text_only=False): data = {} data['barcode'] = self.edBarcode.text() data['title'] = self.edTitle.text() # completer fields for c_field, line_edit in [("author", self.edAuthor), ("s_author", self.edSAuthor), ("publisher", self.edPublisher)]: if not text_only: data[c_field] = self._get_cfield_value(c_field, line_edit.text()) else: data[c_field] = line_edit.text() data['year'] = self.edYear.value() data['price'] = self._locale.toDouble(self.edPrice.text())[0] data['description'] = self.edDescription.toPlainText() if not text_only and self._image_changed and self._image_set: data['image'] = qpixmap_to_qbytearray(self.edImage.pixmap()) data['availability'] = self.radioAvailability.checkedId() return data def setup_model(self): db = Db_Instance("edit_book").get_instance() if not db.open(): self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n""Banco de dados indisponível".decode('utf-8')) QMessageBox.critical(self, unicode("Seareiros - Edição de Livro".decode('utf-8')), message) else: # book self._model = QSqlRelationalTableModel(self, db=db) self._model.setTable("book") self._model.setFilter("id = " + str(self._record_id)) # self._model.setRelation(self.column["author"], QSqlRelation("author", "id", "name")) # self._model.setRelation(self.column["s_author"], QSqlRelation("s_author", "id", "name")) # self._model.setRelation(self.column["publisher"], QSqlRelation("publisher", "id", "name")) self._model.select() self._record = self._model.record(0) # models for setting up qcompleters: # book_in_subject self._book_in_subj_model = QSqlTableModel(self, db=db) self._book_in_subj_model.setTable("book_in_subject") # subject self._subject_model = QSqlTableModel(self, db=db) self._subject_model.setTable("subject") self._subject_model.select() # author self._author_model = QSqlTableModel(self, db=db) self._author_model.setTable("author") self._author_model.select() # s_author self._s_author_model = QSqlTableModel(self, db=db) self._s_author_model.setTable("s_author") self._s_author_model.select() # publisher self._publisher_model = QSqlTableModel(self, db=db) self._publisher_model.setTable("publisher") self._publisher_model.select() # retrieving current subjects, should probably place this elsewhere but it's related to models self._subject_records = [] sql_statement = """SELECT id, name FROM subject s, book_in_subject b_s WHERE s.id = b_s.subject_id AND b_s.book_id = %s """ % str(self._record_id) read_only_subject_model = QSqlQueryModel() read_only_subject_model.setQuery(sql_statement, db) # checking query validity if not read_only_subject_model.lastError().isValid(): self._subj_records = iterate_model(read_only_subject_model) def update_data(self): data = self.extract_input() # checking fields that aren't inserted yet for val, model in [('author', self._author_model), ('s_author', self._s_author_model), ('publisher', self._publisher_model)]: if isinstance(data[val], unicode): # needs to be inserted model.insertRow(0) model.setData(model.index(0,1), data[val]) data[val] = submit_and_get_id(self, model, self.log) if not data[val]: # won't proceed if this fails return False for key,val in data.items(): self._model.setData(self._model.index(0, self.column[key]), val) if 'image' not in data and self._image_changed: # user cleared the image ok = self._model.setData(self._model.index(0, self.column['image']), None) print ok # try to commit changes if not self._model.submitAll(): self.log.error(self._model.lastError().text()) message = unicode("Erro de transação\n\n""Não foi possível salvar no banco de dados".decode('utf-8')) QMessageBox.critical(self, "Seareiros - Edição de Livro", message) return False else: # updating subjects error = False # added subjects for subj in self._added_subjects: # the list has the format [id, text] for existing subjects or [None, text] otherwise if not subj[0]: # need to insert the subject before associating it with the book self._subject_model.insertRow(0) self._subject_model.setData(self._subject_model.index(0,1), subj[1]) subj[0] = submit_and_get_id(self, self._subject_model, self.log) if not subj[0]: error = True break # have a valid record id for the subject to be associated self._book_in_subj_model.insertRow(0) self._book_in_subj_model.setData(self._book_in_subj_model.index(0,0), self._record_id) self._book_in_subj_model.setData(self._book_in_subj_model.index(0,1), subj[0]) ok = self._book_in_subj_model.submitAll() if not ok: error = True self.log.error(self._book_in_subj_model.setLastError().text()) break # removed subjects for removed_id in self._removed_subjects: self._book_in_subj_model.setFilter("book_id = %s AND subject_id = %s" % (str(self._record_id),str(removed_id))) self._book_in_subj_model.select() self._book_in_subj_model.removeRow(0) if self._book_in_subj_model.lastError().isValid(): error = True self.log.error(self._book_in_subj_model.lastError().text()) break if not error: message = unicode("Sucesso!\n\n""O livro foi atualizado com êxito no banco de dados".decode('utf-8')) QMessageBox.information(self, unicode("Seareiros - Edição de Livro".decode('utf-8')), message) else: message = unicode("Erro\n\n""Associado alterado, " "porém ocorreu um problema ao salvar suas atividades".decode('utf-8')) QMessageBox.warning(self, unicode("Seareiros - Edição de Livro".decode('utf-8')), message) # if I don't set this flag here it'll trigger a warning for altering data on the form self._dirty = False return True def _get_id_from_name(self, table, name): db = Db_Instance(table + "_fetch_" + name + "_id").get_instance() if not db.open(): return None else: query = QSqlQuery(db) query.prepare("SELECT id FROM %s WHERE name = :name" % table) query.bindValue(":name", name) query.exec_() if query.next(): return query.record().value("id") else: return None def _get_name_from_id(self, table, id): db = Db_Instance(table + "_fetch_" + str(id) + "_name").get_instance() if not db.open(): return None else: query = QSqlQuery(db) query.prepare("SELECT name FROM %s WHERE id = :id" % table) query.bindValue(":name", id) query.exec_() if query.next(): return query.record().value("name") else: return None @QtCore.Slot() def on_btnAddSubject_clicked(self): txt = self.edSubject.text() if txt != '': id = self._get_id_from_name('subject', self.edSubject.text()) if id: # known register data = [id, txt] else: # new data data = [None, txt] not_a_duplicate = self.add_subject(data) if not_a_duplicate: self.refresh_tableSubjects() self.edSubject.clear() self.edSubject.setFocus() @QtCore.Slot() def on_btnCleanSubjects_clicked(self): self.clear_table() self.edSubject.setFocus() def clear_table(self): # can't directly change activity_list here itens = [i for i in self._subject_list] for item in itens: self.remove_subject(item) self._added_subjects[:] = [] def add_subject(self, data): """ adds a subject to the list except for duplicates """ if data in self._subject_list: return False else: if self.is_in_del_queue(data[0]): self._removed_subjects.remove(data[0]) else: self._added_subjects.append(data) self._subject_list.append(data) # sorts by name self._subject_list.sort(key=operator.itemgetter(1)) return True def refresh_tableSubjects(self): if len(self._subject_list) > 0: self.tableSubjects.setColumnCount(len(self._subject_list[0])+1) col_labels = ["", "Nome", ""] self.tableSubjects.setHorizontalHeaderLabels(col_labels) self.tableSubjects.setColumnHidden(0, True) else: self.tableSubjects.setColumnCount(0) self.tableSubjects.setRowCount(len(self._subject_list)) for i, row in enumerate(self._subject_list): for j, col in enumerate(row): item = QTableWidgetItem(col) self.tableSubjects.setItem(i, j, item) # icon to remove rows individually remove_icon = QIcon(":icons/conn_failed.png") remove_btn = QPushButton(remove_icon, "") remove_btn.clicked.connect(partial(self.remove_subject, subject=row)) self.tableSubjects.setCellWidget(i, len(row), remove_btn) self.tableSubjects.resizeColumnsToContents() self.tableSubjects.horizontalHeader().setResizeMode(1, QHeaderView.Stretch) def is_in_del_queue(self, id): return id in self._removed_subjects def is_in_add_queue(self, data): return data in self._added_subjects def remove_subject(self, subject): # remove a row based on its value self._subject_list.remove(subject) if self.is_in_add_queue(subject): # unqueue previously added activity self._added_subjects.remove(subject) else: id = subject[0] if id: self._removed_subjects.append(id) self.refresh_tableSubjects() def _get_cfield_value(self, c_field, text): if text == '': return None id = self._get_id_from_name(c_field, text) if id: return id else: return text
class BookAddForm(QScrollArea, Ui_BookForm): """ Interface for book input """ column = { "barcode": 1, "title": 2, "author": 3, "s_author": 4, "publisher": 5, "year": 6, "price": 7, "description": 8, "stock": 9, "image": 10, "availability": 11, } IMG_SIZE = (150, 150) def __init__(self, parent=None): super(BookAddForm, self).__init__(parent) self.setupUi(self) # had to subclass this spinbox to support return grabbing self.edYear = ReturnKeySpinBox(self) self.edYearHolder.addWidget(self.edYear) # configuring id's for radio group self.radioAvailability.setId(self.rdSell, 0) self.radioAvailability.setId(self.rdRent, 1) self.radioAvailability.setId(self.rdInactive, 2) self._access = statics.access_level # for currency formatting self._locale = QLocale() # had to hardcode these, wouldn't work otherwise: self.contentsLayout.setAlignment(self.groupBox, QtCore.Qt.AlignTop) self.contentsLayout.setAlignment(self.groupBox_2, QtCore.Qt.AlignTop) self.log = logging.getLogger("BookForm") self.setup_model() self.setup_fields() self._subject_list = [] # flag to indicate whether there were changes to the fields self._dirty = False # for use in selection docks, indicates a saved record self._book_id = None # user did input an image self._image_set = False # overlaying a clean button over the image (couldn't do it in designer) self.btnCleanImage = QPushButton() self.btnCleanImage.setIcon(QIcon(":icons/clean.png")) self.btnCleanImage.setFixedWidth(35) self.btnCleanImage.clicked.connect(self.clear_image) self.btnCleanImage.setVisible(False) clean_img_layout = QVBoxLayout(self.edImage) clean_img_layout.addWidget(self.btnCleanImage) clean_img_layout.setAlignment(Qt.AlignTop | Qt.AlignLeft) clean_img_layout.setContentsMargins(2, 2, 0, 0) def is_dirty(self): return self._dirty def setup_model(self): db = Db_Instance("form_book").get_instance() if not db.open(): self.log.error(db.lastError().text()) message = unicode("Erro de conexão\n\n" "Banco de dados indisponível".decode("utf-8")) QMessageBox.critical(self, "Seareiros - Cadastro de Livro", message) else: # book self._model = QSqlTableModel(self, db=db) self._model.setTable("book") # subject self._subject_model = QSqlTableModel(self, db=db) self._subject_model.setTable("subject") self._subject_model.select() # author self._author_model = QSqlTableModel(self, db=db) self._author_model.setTable("author") self._author_model.select() # sauthor self._s_author_model = QSqlTableModel(self, db=db) self._s_author_model.setTable("s_author") self._s_author_model.select() # publisher self._publisher_model = QSqlTableModel(self, db=db) self._publisher_model.setTable("publisher") self._publisher_model.select() # book subjects self._book_in_subj_model = QSqlTableModel(self, db=db) self._book_in_subj_model.setTable("book_in_subject") def setup_fields(self): """ setting up validators and stuff """ # validators # forcing uppercasing on these fields self.edTitle.setValidator(UppercaseValidator()) self.edAuthor.setValidator(UppercaseValidator()) self.edSAuthor.setValidator(UppercaseValidator()) self.edPublisher.setValidator(UppercaseValidator()) self.edPrice.setValidator(CurrencyValidator(self.edPrice)) self.edBarcode.setValidator(NumericValidator()) self.edYear.setMinimum(1900) self.edYear.setMaximum(date.today().year) self.edYear.setValue(date.today().year) # fixing tab order self.setTabOrder(self.edPublisher, self.edYear) self.setTabOrder(self.edYear, self.edPrice) # connecting return key to tab lineEditList = self.findChildren(QLineEdit) for lineEdit in lineEditList: # had some problem with C++ originated objects if lineEdit.objectName() not in ["qt_spinbox_lineedit", "edSubject"]: lineEdit.returnPressed.connect(lineEdit.focusNextChild) # detect changes on line edits lineEdit.textChanged.connect(self.check_changes) # different behaviour for these self.edBarcode.textChanged.connect(self.check_barcode) self.edSubject.returnPressed.connect(self.on_btnAddSubject_clicked) # completers config_completer(self.edSubject, self._subject_model, "name") config_completer(self.edAuthor, self._author_model, "name") config_completer(self.edSAuthor, self._s_author_model, "name") config_completer(self.edPublisher, self._publisher_model, "name") # making image clickable clickable(self.edImage).connect(self.handle_image) def clear_image(self): img = QImage(":icons/no_image.png") self.set_image(img) self._image_set = False self.btnCleanImage.setVisible(False) def handle_image(self): image_path = QFileDialog.getOpenFileName( self, "Escolha uma imagem", os.getenv("HOME"), "Imagens (*.png, *.jpg *.bmp)" )[0] if os.path.exists(image_path): self.set_image(QImage(image_path)) self._image_set = True self.btnCleanImage.setVisible(True) def set_image(self, img): pix = QPixmap.fromImage(img) pix = pix.scaled(self.IMG_SIZE[0], self.IMG_SIZE[1], Qt.KeepAspectRatio) self.edImage.setPixmap(pix) self.edImage.setScaledContents(True) def check_changes(self, txt): if txt != "": self._dirty = True def check_barcode(self, txt): if len(txt) == self.edBarcode.maxLength(): self.edBarcode.focusNextChild() def _get_id_from_name(self, table, name): db = Db_Instance(table + "_fetch_" + name + "_id").get_instance() if not db.open(): return None else: query = QSqlQuery(db) query.prepare("SELECT id FROM %s WHERE name = :name" % table) query.bindValue(":name", name) query.exec_() if query.next(): return query.record().value("id") else: return None def submit_data(self): data = self.extract_input() # checking fields that aren't inserted yet for val, model in [ ("author", self._author_model), ("s_author", self._s_author_model), ("publisher", self._publisher_model), ]: if isinstance(data[val], unicode): # needs to be inserted model.insertRow(0) model.setData(model.index(0, 1), data[val]) data[val] = submit_and_get_id(self, model, self.log) if not data[val]: # won't proceed if this fails return False # filling a book row self._model.insertRow(0) for key, val in data.items(): self._model.setData(self._model.index(0, self.column[key]), val) book_id = submit_and_get_id(self, self._model, self.log) if book_id: # for use in selection docks self.setBookId(book_id) # book sucessfully added, now associating related subjects subjects, new_subjects = self.extract_subjects_input() for subj in new_subjects: self._subject_model.insertRow(0) self._subject_model.setData(self._subject_model.index(0, 1), subj) id = submit_and_get_id(self, self._subject_model, self.log) if not id: # issue saving new subject return False subjects.append(int(id)) # associating book and it's subjects error = False for subj_id in subjects: self._book_in_subj_model.insertRow(0) self._book_in_subj_model.setData(self._book_in_subj_model.index(0, 0), book_id) self._book_in_subj_model.setData(self._book_in_subj_model.index(0, 1), subj_id) ok = self._book_in_subj_model.submitAll() if not ok: error = True break if error: self.log.error(self._book_in_subj_model.lastError.text()) message = unicode( "Erro\n\n" "Livro cadastrado, porém ocorreu um problema ao" " salvar os temas a que está associado".decode("utf-8") ) QMessageBox.warning(self, "Seareiros - Cadastro de Livro", message) return False else: message = unicode("Sucesso!\n\n" "O livro foi salvo com êxito no banco de dados".decode("utf-8")) QMessageBox.information(self, "Seareiros - Cadastro de Livro", message) return True # failed to insert a row return False def setBookId(self, id): self._book_id = id def get_added_record(self): db = Db_Instance("added_book_record").get_instance() if db.open() and self._book_id: query = QSqlQuery(db) query.prepare("SELECT * FROM book WHERE id = :id") query.bindValue(":id", self._book_id) query.exec_() if query.next(): return query.record() else: return None else: return None def clear(self): self._dirty = False lineEditList = self.findChildren(QLineEdit) for lineEdit in lineEditList: lineEdit.clear() self.clear_table() self.clear_image() self.edBarcode.setFocus() @QtCore.Slot() def on_btnAddSubject_clicked(self): txt = self.edSubject.text() if txt != "": id = self._get_id_from_name("subject", self.edSubject.text()) if id: # known register data = [id, txt] else: # new data data = [None, txt] not_a_duplicate = self.add_subject(data) if not_a_duplicate: self.refresh_tableSubjects() self.edSubject.clear() self.edSubject.setFocus() @QtCore.Slot() def on_btnCleanSubjects_clicked(self): self.clear_table() self.edSubject.setFocus() def clear_table(self): self._subject_list = [] self.tableSubjects.clear() self.refresh_tableSubjects() def add_subject(self, data): """ adds a subject to the list except for duplicates """ if data in self._subject_list: return False else: self._subject_list.append(data) # sorts by name self._subject_list.sort(key=operator.itemgetter(1)) return True def refresh_tableSubjects(self): if len(self._subject_list) > 0: self.tableSubjects.setColumnCount(len(self._subject_list[0]) + 1) col_labels = ["", "Nome", ""] self.tableSubjects.setHorizontalHeaderLabels(col_labels) self.tableSubjects.setColumnHidden(0, True) else: self.tableSubjects.setColumnCount(0) self.tableSubjects.setRowCount(len(self._subject_list)) for i, row in enumerate(self._subject_list): for j, col in enumerate(row): item = QTableWidgetItem(col) self.tableSubjects.setItem(i, j, item) # icon to remove rows individually remove_icon = QIcon(":icons/conn_failed.png") remove_btn = QPushButton(remove_icon, "") remove_btn.clicked.connect(partial(self.remove_subject, subject=row)) self.tableSubjects.setCellWidget(i, len(row), remove_btn) self.tableSubjects.resizeColumnsToContents() self.tableSubjects.horizontalHeader().setResizeMode(1, QHeaderView.Stretch) def remove_subject(self, subject): # remove a row based on its value self._subject_list.remove(subject) self.refresh_tableSubjects() def extract_input(self): data = {} data["barcode"] = self.edBarcode.text() data["title"] = self.edTitle.text() # completer fields for c_field, line_edit in [ ("author", self.edAuthor), ("s_author", self.edSAuthor), ("publisher", self.edPublisher), ]: data[c_field] = self._get_cfield_value(c_field, line_edit.text()) data["year"] = self.edYear.value() data["price"] = self._locale.toDouble(self.edPrice.text())[0] data["description"] = self.edDescription.toPlainText() if self._image_set: data["image"] = qpixmap_to_qbytearray(self.edImage.pixmap()) data["availability"] = self.radioAvailability.checkedId() return data def _get_cfield_value(self, c_field, text): if text == "": return None id = self._get_id_from_name(c_field, text) if id: return id else: return text def extract_subjects_input(self): # grab id of selected activities subjects = [] new_subjects = [] for subj in self._subject_list: if subj[0]: # selected from previously added subjects subjects.append(subj[0]) else: # new subject new_subjects.append(subj[1]) return (subjects, new_subjects)
class IntervenantUI(TableUI): """Classe chargée de l'interface de gestion des intervenants""" def setupModel(self): u"""Définit et configure le modèle sous-jacent à la table""" self._modele = QSqlTableModel(self) self._modele.setTable("intervenant") self._modele.setHeaderData(1, Qt.Horizontal, "Nom") self._modele.setHeaderData(2, Qt.Horizontal, u"Téléphone") self._modele.setHeaderData(3, Qt.Horizontal, "Email") self._modele.setEditStrategy(QSqlTableModel.OnFieldChange) self._modele.select() self._ui.tv.setModel(self._modele) def msgValidationNouveau(self): u"""Message d'erreur quand on veut créer deux items de suite""" return u"Valider l'intervenant avant d'en recréer un nouveau" def titreErrSuppression(self): return u"Cliquer sur l'intervenant à supprimer" def msgErrSuppression(self): return u"""Veuiller cliquer sur un intervenant avant de cliquer sur \ supprimer""" def msgSuppression(self, index): return u"Êtes-vous sûr de vouloir supprimer l'intervenant " + index.sibling( index.row(), 1).data() + " ? " def preSupprVerification(self, index): u"""Vérification à effectuer avant d'autoriser à supprimer un item Renvoit False si la suppression est interdite """ sql = """ SELECT COUNT(*) FROM absence WHERE id_intervenant=""" + str(index.sibling(index.row(), 0).data()) req = QSqlQuery() if req.exec_(sql): req.next() nbAbsences = req.record().value(0) if nbAbsences != 0: pl = "" if nbAbsences != 1: pl = "s" QMessageBox.critical( self, "Impossible de suppprimer", u"L'intervenant a encore " + str(nbAbsences) + u" absence" + pl + u" enregistrée" + pl + "<br />" + u"Il faut les supprimer avant") # TODO trouver un moyen de setter l'onglet de l'application # self._ui.tabWidget.setCurrentIndex(1) return False # TODO gérer le else, au moins logger quelque chose return True
class IntervenantUI(TableUI): """Classe chargée de l'interface de gestion des intervenants""" def setupModel(self): u"""Définit et configure le modèle sous-jacent à la table""" self._modele = QSqlTableModel(self) self._modele.setTable("intervenant") self._modele.setHeaderData(1, Qt.Horizontal, "Nom") self._modele.setHeaderData(2, Qt.Horizontal, u"Téléphone") self._modele.setHeaderData(3, Qt.Horizontal, "Email") self._modele.setEditStrategy(QSqlTableModel.OnFieldChange) self._modele.select() self._ui.tv.setModel(self._modele) def msgValidationNouveau(self): u"""Message d'erreur quand on veut créer deux items de suite""" return u"Valider l'intervenant avant d'en recréer un nouveau" def titreErrSuppression(self): return u"Cliquer sur l'intervenant à supprimer" def msgErrSuppression(self): return u"""Veuiller cliquer sur un intervenant avant de cliquer sur \ supprimer""" def msgSuppression(self, index): return u"Êtes-vous sûr de vouloir supprimer l'intervenant " + index.sibling(index.row(), 1).data() + " ? " def preSupprVerification(self, index): u"""Vérification à effectuer avant d'autoriser à supprimer un item Renvoit False si la suppression est interdite """ sql = """ SELECT COUNT(*) FROM absence WHERE id_intervenant=""" + str(index.sibling(index.row(), 0).data()) req = QSqlQuery() if req.exec_(sql): req.next() nbAbsences = req.record().value(0) if nbAbsences != 0: pl = "" if nbAbsences != 1: pl = "s" QMessageBox.critical(self, "Impossible de suppprimer", u"L'intervenant a encore " + str(nbAbsences) + u" absence" + pl + u" enregistrée" + pl + "<br />" + u"Il faut les supprimer avant") # TODO trouver un moyen de setter l'onglet de l'application # self._ui.tabWidget.setCurrentIndex(1) return False # TODO gérer le else, au moins logger quelque chose return True
def log_to_history(db_session, type, id_ref, description): """ logs a short summary to be displayed on the overview dock """ # history model = QSqlTableModel(db=db_session) model.setTable("history") model.insertRow(0) model.setData(model.index(0,1), type) model.setData(model.index(0,2), id_ref) model.setData(model.index(0,3), description) model.setData(model.index(0,5), statics.username) if model.submitAll(): return True return False