import QtQuick
import QtQuick.Controls 2.15
import QtQuick.Layouts 6.3
Page {
width: root.width
height: root.height
visible: true
background: Rectangle {
color: "white"
}
Text{
id: stageText
anchors.horizontalCenter: parent.horizontalCenter
topPadding: root.height / 4
font.pixelSize: 26
text: ""
color: "black"
}
ColumnLayout {
width: parent.width
height: parent.height
scale: root.width / 1000.0
RowLayout{
Layout.alignment: Qt.AlignCenter
spacing: 0
id: visualizeRow
property string myArr : hammingCode.getDataStr();
Repeater {
model: visualizeRow.myArr.length
Rectangle {
id: bit
width: 50
height: 50
Text {
anchors.centerIn: parent
text: visualizeRow.myArr.charAt(index)
color: "black"
}
border.width: 1
color: "white"
}
}
Component.onCompleted: {
stageText.text = "Encoding";
hammingCode.encodeData(true);
}
}
}
Connections{
target: hammingCode
function onTurnBitOff(index){
bit[index].color = "black";
}
function onTurnBitOn(index){
bit[index].color = "red";
}
//put signals from c++ here that change visual stuff and shit
}
}
I have a Page which using Repeater creates an array from a string of '0' and '1', it looks like this: Application screenshot
What i would like to do is change the color of a certain rectangle, access a certain rectangle at given index in the Connections functions which are connected to c++ signals.
The code in the functions doesn't work (it says "bit" is undefined), but illustrates what i would like to achieve. How can this be achieved?
Your C++ seems to offer getDataStr() as a method returning a string array. Consider changing it to a property and, reconsider the type. If your data type is an array of "1" and "0" the more efficient type for that should be just integer.
public:
Q_PROPERTY(int data READ data WRITE setData NOTIFY dataChanged)
Q_INVOKABLE void setBit(int index) { setData(data() |= (1 << index)); }
Q_INVOKABLE void clearBit(int index) { setData(data() &= ~(1 << index)); }
Q_INVOKABLE void toggleBit(int index) { setData(data() ^= (1 << index)); }
Q_INVOKABLE bool isSet(index) { return (data() & (1 << index)) != 0; }
signals:
void dataChanged();
protected:
int m_data;
int data() const { return m_data; }
void setData(int data) { if (m_data != data) { m_data = data; dataChanged(); } }
Then, you can use that to populate your Repeater and set both the text and color based on the value returned by isSet(index)
.
In the following example, I've mocked the C++ hammingCode implementation with a QtObject
lookalike plus I've optimized/replaced the Repeater
with a ListView
. Note that because the left-most top bit is bit 6, hence why you will see 6-index
math in checking the bits:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
QtObject {
id: hammingCode
property int data: 127
function setBit(index) { data |= (1 << index); }
function clearBit(index) { data &= ~(1 << index); }
function toggleBit(index) { data ^= (1 << index); }
function isSet(index) { return (data & (1 << index)) != 0; }
}
ColumnLayout {
anchors.centerIn: parent
spacing: 50
Label {
Layout.alignment: Qt.AlignHCenter
text: qsTr("Hamming Code: %1").arg(hammingCode.data)
}
ListView {
Layout.preferredWidth: 50 * 7
Layout.preferredHeight: 50
orientation: ListView.Horizontal
model: 7
delegate: Rectangle {
property bool bitSet: hammingCode.isSet(6-index)
property color bitColor: bitSet ? "red" : "black"
width: 50
height: 50
border.color: bitColor
Text {
anchors.centerIn: parent
text: bitSet ? "1" : "0"
color: bitColor
}
MouseArea {
anchors.fill: parent
onClicked: hammingCode.toggleBit(6-index)
}
}
}
}
}
You can Try it Online!