我有一个数独网格,我想验证它,以便不能在同一行和同一列中输入数字。如果发生这种情况,我希望打开消息对话框。
我有一个函数
verif_complet
检查行和列。我发出了一个信号,但它无法正常工作,并且消息对话框未打开。
可能出现什么问题,我该怎么做才能使这项工作正常进行?
这是
TableView
的QML代码:
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"
}
}
}
这是消息对话框:
MessageDialog {
id: msgDial
text: "Invalid number."
informativeText: "Do you want to save your changes?"
buttons: MessageDialog.Ok
onAccepted: msgDial.close()
}
这是信号和QML之间的连接来打开消息对话框,但是消息对话框没有打开。
Connections {
target: grid
function onInvalidInput() {
msgDial.open()
}
}
这是
setData
函数的C++代码:
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;
}
这是
verif_complet
函数:
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;
}
我尝试调用
verif_complet
函数并发出信号。
您可以使用
RegularExpressionValidator
而不是 IntValidator
构建解决方案。正则表达式将首先允许“0123456789”中的字符,但随着时间的推移,可用字符列表会随着您输入新值而消失。
因为我们确保输入始终有效,所以不需要后期编辑检查,也不需要对话框。
import QtQuick
import QtQuick.Controls
Page {
title: "Sudoku Test"
Repeater {
model: SudokuModel { id: sudokuModel}
delegate: SudokuCell {
debug: debugCheckBox.checked
onActiveFocusChanged: if (activeFocus) updateValidChars()
function updateValidChars() {
let ok = "0123456789".split("");
for (let idx = 0; idx < sudokuModel.count; idx++) {
let m = sudokuModel.get(idx);
if (m.i === i && m.j === j) continue;
if (m.i !== i && m.j !== j) continue;
if (m.v === 0) continue;
if (m.v < 1 || m.v > 9) continue;
ok[m.v] = "";
}
validChars = ok.join("");
}
}
}
footer: Frame {
CheckBox { id: debugCheckBox; text: "Debug" }
}
}
// SudokuModel.qml
import QtQuick
ListModel {
Component.onCompleted: {
for (let i = 0; i < 9; i++)
for (let j = 0; j < 9; j++)
append( {i:i,j:j,v:0} );
}
}
// SudokuCell.qml
import QtQuick
import QtQuick.Controls
TextField {
property bool debug: false
property var validChars: "0123456789";
property var regex: new RegExp('^[' + validChars + ']$');
property int cellSize: debug ? 60 : 40
background: Rectangle {
border.color: "black"
Text {
visible: debug
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 2
text: validChars; font.pointSize: 6
}
}
x: j * cellSize
y: i * cellSize
width: cellSize
height: cellSize
color: acceptableInput ? "green" : "red"
text: v
validator: RegularExpressionValidator { regularExpression: regex }
onEditingFinished: v = parseInt(text)
}
您可以在线尝试!