Model view insert row validation question isDirty()???
-
I have two sql relational tables and two delegates. The first model stores the recipes. The second table stores the join between recipe and ingredients. The second table has a proxy set to only show rows for each recipe. I am achieving this with a proxy model. This would be a left outer join.
I have a sql relational table model with a delegate. What is the best way to prevent the user from adding more rows before the user specifies a value? I am using on manual submit. The first two columns are populated programmatically. The third column needs user input. I only want to submit the row once the user specifies a value. And I only want the user to be able to add a new row once the user defines the third column?
Can I use isDirty() for this?
self.join_model.dataChanged.connect(partial(self.submitrow, MissData = self.MissData)) def submitrow(self, MissData): self.MissData = MissData # Do not evaluate value when GUI loads data on initalization if self.MissData == False: self.join_model.submitAll() # Set this to true because the user entered a value identical to another CFR self.MissData = True if self.join_model.lastError().isValid(): #print self.join_model.lastError().text() if self.join_model.lastError().text() == "columns planning_obj_id, cfr_lu_id are not unique Unable to fetch row": self.join_model.revertAll() msg = "rows are not unique in the table" QtGui.QMessageBox.warning(self, "warning", msg, QtGui.QMessageBox.Ok) self.MissData = False def AddJoinRow(self): """this will allow one to add a row into the bottom model. This tool is a many to many relationship between recipes and ingrendents. Ingredients are popluated by the program. This is a many to many relationship. This tool has to models and two views the top model handles the recipes and the bottom model handles the ingredients. """ ## recipe row count recipe_count = self.obj_model.rowCount() ## this is to test if there is at least one recipe id. if recipe_count == 0: msg = "you must add a recipe before you can add a row to the join table." QtGui.QMessageBox.warning(self, "warning", msg, QtGui.QMessageBox.Ok) return ## else there is at least one row in the recipe model. else: ## get the selected row in the recipe table. selected_index = self.obj_tableView.currentIndex() ## this tests if there is not a selected index in the recipe model. if not selected_index.isValid(): msg = "you must select a recipe row before adding a row in the " QtGui.QMessageBox.warning(self, "warning", msg, QtGui.QMessageBox.Ok) return ## else there is a selected index in the planning objective model. else: ## get the row index of the selected recipe row_index = selected_index.row() max_id = 1 query = QtSql.QSqlQuery() ##Query the join database table to get the max id query.exec_("SELECT MAX(id) FROM join_recipe_ingredents") if query.next(): max_id = query.value(0).toInt()[0] ## query the recipe model to get the recipe id from the top model. ## cannot use rowcount because a user can remove a row. recipe_id = self.obj_model.data(self.obj_model.index(row_index, ID)).toInt()[0] ## get the row count of the join table. join_row = self.join_model.rowCount() if join_row <4: ## insert a row into the model. self.join_model.insertRow(0) ## set column 1 value to be the max id + 1 self.join_model.setData(self.join_model.index(0, JOIN_ID), max_id + 1) ## set column 2 value to be the recipe_id self.join_model.setData(self.join_model.index(0, PLANNING_ID), recipe_id) ## column 3 is a combo box of all the ingrendents. I am using setRelation to populate this combobox. else: msg = "Cannot have more than 4 rows" QtGui.QMessageBox.warning(self, "warning", msg, QtGui.QMessageBox.Ok)
-
Hi,
Then why not use a dialog where you ask for the user input and only then update your database ?
-
Sure you can, but it's not the table's role to ask for more information if something is missing.
-
Maybe I am not asking the right question. How do you wait for the user to input a value and only then call submitAll? It cant be in the add row method because that would only get called when the user pushes the button to add a row. I need to wait and allow the user to choose a value before submitAll is called.
-
If you have e.g. a button to add a new row, have a custom slot connected to the button clicked signal and in that slot request input from the user and only once your have it, add the row.