我有一个 TableView,其中有一个数独网格。我想验证它,以便不能使用 C++ 函数将数字放置在同一行或同一列中。当用户输入无效数字时,应该会出现 MessageDialog,但这种情况不会发生。可能是什么问题? 这是对话框和:
MessageDialog {
id: msgDial
text: "Invalid number."
informativeText: "Do you want to save your changes?"
buttons: MessageDialog.Ok
onAccepted: msgDial.close()
}
这是我要验证的TableView:
TableView {
anchors.fill: parent
clip: true
model: SudokuGrid {
id: grid
}
delegate: Rectangle {
required property var model
implicitWidth: 50
implicitHeight: 50
TextField {
anchors.fill: parent
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" : "lightblue"
border {
width: 1
color: "white"
}
}
color: "black"
validator: IntValidator {
bottom: 1
top: 9
}
onEditingFinished: {
if (text !== "" && model.display === 0) {
var enteredNumber = parseInt(text);
if (validator.validate(text, 0).valid && model.isNumberValid(model.row, model.column, enteredNumber)) {
model.display = text;
} else {
msgDial.open();
}
}
}
TableView.onCommit: {
if (text !== "" && model.display === 0) {
var enteredNumber = parseInt(text);
if (validator.validate(text, 0).valid && model.isNumberValid(model.row, model.column, enteredNumber)) {
model.display = text;
} else {
msgDial.open();
}
}
}
}
这是 C++ 代码及其 setData:
bool Grid::isNumberValid(int row, int col, int number) const
{
for (int j = 0; j < 9; j++) {
if (j != col && gridData[row][j] == number) {
return false;
}
}
for (int i = 0; i < 9; i++) {
if (i != row && gridData[i][col] == number) {
return false;
}
}
return true;
}
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;
if (isNumberValid(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 or column!";
}
}
return false;
}
也许我使用 id 而不是使用 setContextProperty 传递给 qml 的对象来创建数独网格的类,这可能是问题所在?我是 qml 新手,我不知道问题出在哪里。
要使用验证器,您不应调用
validate
方法,您应该检查 acceptableInput
属性。例如:
TextField {
id: textField
validator: IntValidator { bottom: 1; top: 9 }
background: Rectangle {
color: textField.acceptableInput ? "green" : "red"
}
}
由于此属性在编辑过程中持续可用,因此我认为无需等待
onAccepted
/onEditingFinished
。事实上,如果输入无效,这样的验证器的存在将阻止 onAccepted
/onEditingFinished
被引发。所以显示对话框的方法实际上行不通。