I have a sudoku grid, and I want to validate it so that a number cannot be entered in the same row and column. If this happens, I want the message dialog box to open.
I have the function verif_complet that checks the row and column. I emitted a signal, but it is not working correctly, and the message dialog is not opening.
What could be the problem and what can I do to make this work?
This is the QML code of the TableView:
TableView {
anchors.fill: parent
clip: true
model: SudokuGrid {
id: grid
}
delegate: Rectangle {
required property var model
implicitWidth: 50
implicitHeight: 50
TextField {
id: textField
anchors.fill: parent
validator: IntValidator { bottom: 1; top: 9 }
text: model.display !== undefined ? model.display.toString() : ""
readOnly: model.display !== undefined && model.display !== 0
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
background: Rectangle {
color: model.row % 2 ? "lightpink" : "#bfa6ac" && textField.acceptableInput ? "#FFEFD5" : "#bfa6ac"
border {
width: 1
color: "white"
}
}
color: "black"
onEditingFinished: {
if (!model.verif_complet(model.row, model.column, parseInt(textField.text))) {
grid.invalidInput();
}
}
}
Rectangle {
width: 1
height: parent.height
color: model.column % 3 == 0 ? "black" : "transparent"
}
Rectangle {
width: parent.width
height: 1
color: model.row % 3 == 0 ? "black" : "transparent"
}
}
}
This is the message dialog:
MessageDialog {
id: msgDial
text: "Invalid number."
informativeText: "Do you want to save your changes?"
buttons: MessageDialog.Ok
onAccepted: msgDial.close()
}
This is the connection between the signal and QML to open the message dialog, but the message dialog is not opening.
Connections {
target: grid
function onInvalidInput() {
msgDial.open()
}
}
This is the C++ code of the setData function:
bool Grid::setData(const QModelIndex &index, const QVariant &value, int role) {
if (role == Qt::EditRole) {
if (!checkIndex(index))
return false;
int inputValue = value.toInt();
if (inputValue < 1 || inputValue > 9)
return false;
SudokuGenerator sudokuGenerator(1);
if (sudokuGenerator.verif_complet(index.row(), index.column(), inputValue)) {
gridData[index.row()][index.column()] = inputValue;
emit dataChanged(index, index);
return true;
} else {
qDebug() << "Invalid number in the same row, column, or 3x3 square!";
emit invalidInput();
}
}
return false;
}
and this is the verif_complet function:
bool SudokuGenerator::verif_complet(int i, int j, int nr) {
if (verif_col(j, nr) == true && verif_lin(i, nr) == true && verif_patrat(i - (i % 3), j - (j % 3), nr) == true)
return true;
return false;
}
I tried to call the verif_complet function and emit a signal.
You can build a solution using
RegularExpressionValidatorinstead ofIntValidator. The regular expression will begin by allowing the characters from "0123456789" but, over time, the list of available characters disappears as you enter new values.Because we're ensuring the input is always valid, there is no need for a post-editing check and no need for a dialog.
You can Try it Online!