I recognized in my example a small gap between the repeated objects about one pixel more or less. Depending on the property int size
this gap might change position. I also tested with property double size
but this seem not changing the effect.
// FILE main.qml
import QtQuick 2.11
import QtQuick.Controls 2.4
Rectangle {
width: 640
height: 320
BarrierTape {}
}
// File BarrierTape.qml
import QtQuick 2.11
import QtQuick.Layouts 1.11
Item {
id: barrierTape
property int size: 100
x:200
y:100
ColumnLayout {
spacing: barrierTape.size * Math.sin(Math.PI/3)
Repeater {
model: 2
Rectangle {
width: barrierTape.size
height: barrierTape.size * Math.sin(Math.PI/3)
color: "#ffd100"
}
}
}
ColumnLayout {
x: -barrierTape.size*3/4
y: barrierTape.size/2 * Math.sin(Math.PI/3)
spacing: barrierTape.size * Math.sin(Math.PI/3)
Repeater {
model: 2
Rectangle {
width: barrierTape.size
height: barrierTape.size * Math.sin(Math.PI/3)
color: "#ffd100"
}
}
}
ColumnLayout {
x: barrierTape.size*3/4
y: -barrierTape.size/2 * Math.sin(Math.PI/3)
spacing: barrierTape.size * Math.sin(Math.PI/3)
Repeater {
model: 2
Rectangle {
width: barrierTape.size
height: barrierTape.size * Math.sin(Math.PI/3)
color: "#ffd100"
}
}
}
ColumnLayout {
spacing: barrierTape.size * Math.sin(Math.PI/3)
y: barrierTape.size * Math.sin(Math.PI/3)
Repeater {
model: 2
Rectangle {
width: barrierTape.size
height: barrierTape.size * Math.sin(Math.PI/3)
color: "#222222"
}
}
}
ColumnLayout {
x: -barrierTape.size * 3/4
y: barrierTape.size * 3/2 * Math.sin(Math.PI/3)
spacing: barrierTape.size* Math.sin(Math.PI/3)
Repeater {
model: 2
Rectangle {
width: barrierTape.size
height: barrierTape.size * Math.sin(Math.PI/3)
color: "#222222"
}
}
}
ColumnLayout {
x: barrierTape.size * 3/4
y: barrierTape.size * 1/2 * Math.sin(Math.PI/3)
spacing: barrierTape.size* Math.sin(Math.PI/3)
Repeater {
model: 2
Rectangle {
width: barrierTape.size
height: barrierTape.size * Math.sin(Math.PI/3)
color: "#222222"
}
}
}
}
Further the code have a lot of Boilerplate and I don't know how to achieve the same behavior with less. I thought that creating first an item with all six rectangles and than repeating them would help, but if I put Repeater
in one ColumnLayout seems to ignoring the x
and y
values. I struggle to refactor this file.
EDIT 1:
This is a sample of what it kind of should look like:
CodePudding user response:
This uses a slightly complicated Hexagon component which I did a while ago.
main.qml
import QtQuick
Window {
id: root
width: 640
height: 640
visible: true
title: qsTr("Hello World")
color: "#444444"
property color color1: "#ffd100"
property color color2: "#222222"
property int hexRadius: 50
property real hexInnerRadius: (Math.sqrt(3) / 2) * root.hexRadius
property int spacing: 2
component BarrierTape : Column {
spacing: root.spacing
Repeater {
model: 4
Item {
width: root.hexRadius * 1.5
height: 2 * root.hexInnerRadius
Hexagon {
anchors.centerIn: parent
width: 2 * root.hexRadius
height: 2 * root.hexRadius
radius: 10
fillColor: (index % 2 == 0) ? root.color1 : root.color2
antialiasing: true
}
}
}
}
Row {
x: 100
y: 150
spacing: root.spacing
Repeater {
model: 4
BarrierTape {
y: index * -root.hexInnerRadius
}
}
}
}
Hexagon.qml
import QtQuick
import QtQuick.Shapes
Shape {
id: root
width: 200
height: 200
property int radius: 10
property alias fillColor: path.fillColor
layer.enabled: root.antialiasing
layer.smooth: root.antialiasing
layer.samples: root.antialiasing ? 4 : 0
ShapePath {
id: path
joinStyle: ShapePath.MiterJoin
strokeWidth: 0
strokeColor: "transparent"
startX: 0
startY: 0
}
onRadiusChanged: {
// Only construct polygon if radius changed from 0 to 1 or vice versa.
if ((root.radius root.__previousRadius) === 1)
root.constructPolygon()
root.__previousRadius = root.radius
}
Component.onCompleted: root.constructPolygon()
property real __centerX: root.width / 2
property real __centerY: root.height / 2
property real __radius: Math.min(root.width, root.height) / 2
property int __previousRadius: root.radius
property int minRadius: 0
property int maxRadius: root.__radius * Math.cos(root.toRadians(180.0 / 6))
property int __actualRadius: Math.max(root.minRadius, Math.min(root.maxRadius, root.radius))
function constructPolygon() {
root.clearPathElements()
if (root.radius === 0)
root.constructNonRoundedPolygonPath()
else
root.constructRoundedPolygonPath()
}
function toRadians(degrees) {
return degrees * (Math.PI / 180.0)
}
function constructNonRoundedPolygonPath() {
for (var cornerNumber = 0; cornerNumber < 6; cornerNumber ) {
let angleToCorner = root.toRadians(cornerNumber * (360.0 / 6))
if (cornerNumber === 0) {
path.startX = Qt.binding(function() {
return root.__centerX root.__radius * Math.cos(0)
})
path.startY = Qt.binding(function() {
return root.__centerY root.__radius * Math.sin(0)
})
} else {
let pathLine = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path)
pathLine.x = Qt.binding(function() {
return root.__centerX root.__radius * Math.cos(angleToCorner)
})
pathLine.y = Qt.binding(function() {
return root.__centerY root.__radius * Math.sin(angleToCorner)
})
path.pathElements.push(pathLine)
}
}
// Close the polygon
var pathLineClose = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path)
pathLineClose.x = Qt.binding(function() { return path.startX } )
pathLineClose.y = Qt.binding(function() { return path.startY } )
path.pathElements.push(pathLineClose)
}
property real __halfInteriorCornerAngle: 90 - (180.0 / 6)
property real __halfCornerArcSweepAngle: 90 - root.__halfInteriorCornerAngle
property real __distanceToCornerArcCenter: root.__radius - root.__actualRadius /
Math.sin(root.toRadians(root.__halfInteriorCornerAngle))
function constructRoundedPolygonPath() {
for (var cornerNumber = 0; cornerNumber < 6; cornerNumber ) {
let angleToCorner = cornerNumber * (360.0 / 6)
let pathArc = Qt.createQmlObject('import QtQuick 2.15; PathArc {
property real centerX;
property real centerY }', path)
pathArc.centerX = Qt.binding(function() {
return root.__centerX root.__distanceToCornerArcCenter
* Math.cos(root.toRadians(angleToCorner))
})
pathArc.centerY = Qt.binding(function() {
return root.__centerY root.__distanceToCornerArcCenter
* Math.sin(root.toRadians(angleToCorner))
})
pathArc.x = Qt.binding(function() {
return pathArc.centerX root.__actualRadius
* (Math.cos(root.toRadians(angleToCorner root.__halfCornerArcSweepAngle)))
})
pathArc.y = Qt.binding(function() {
return pathArc.centerY root.__actualRadius
* (Math.sin(root.toRadians(angleToCorner root.__halfCornerArcSweepAngle)))
})
pathArc.radiusX = Qt.binding(function() { return root.__actualRadius })
pathArc.radiusY = Qt.binding(function() { return root.__actualRadius })
if (cornerNumber === 0) {
path.startX = Qt.binding(function() {
return pathArc.centerX root.__actualRadius
* (Math.cos(root.toRadians(angleToCorner - root.__halfCornerArcSweepAngle)))
})
path.startY = Qt.binding(function() {
return pathArc.centerY root.__actualRadius
* (Math.sin(root.toRadians(angleToCorner - root.__halfCornerArcSweepAngle)))
})
} else {
let pathLine = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path)
pathLine.x = Qt.binding(function() {
return pathArc.centerX root.__actualRadius
* (Math.cos(root.toRadians(angleToCorner - root.__halfCornerArcSweepAngle)))
})
pathLine.y = Qt.binding(function() {
return pathArc.centerY root.__actualRadius
* (Math.sin(root.toRadians(angleToCorner - root.__halfCornerArcSweepAngle)))
})
path.pathElements.push(pathLine)
}
path.pathElements.push(pathArc)
}
// Close the polygon
var pathLineClose = Qt.createQmlObject('import QtQuick 2.15; PathLine {}', path)
pathLineClose.x = Qt.binding(function() { return path.startX} )
pathLineClose.y = Qt.binding(function() { return path.startY} )
path.pathElements.push(pathLineClose)
}
function clearPathElements() {
for (var i = 0; i !== path.pathElements.length; i)
path.pathElements[i].destroy()
path.pathElements = []
}
}
CodePudding user response:
I have been having great success at using SVG and a Button hack for rendering SVGs in different colors:
import QtQuick 2.15
import QtQuick.Controls 2.15
Page {
background: Rectangle { color: "#444444" }
Hex { x: 87.5; y: 150; color: "#ffd100" }
Hex { x: 175; y: 100; color: "#ffd100" }
Hex { x: 262.5; y: 50; color: "#ffd100" }
Hex { x: 87.5; y: 450; color: "#222222" }
Hex { x: 175; y: 400; color: "#222222" }
Hex { x: 262.5; y: 350; color: "#222222" }
Hex { x: 87.5; y: 350; color: "#ffd100" }
Hex { x: 175; y: 300; color: "#ffd100" }
Hex { x: 262.5; y: 250; color: "#ffd100" }
Hex { x: 87.5; y: 250; color: "#222222" }
Hex { x: 175; y: 200; color: "#222222" }
Hex { x: 262.5; y: 150; color: "#222222" }
}
//Hex.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
Item {
property alias color: btn.icon.color
Item {
anchors.centerIn: parent
width: 200
height: 200
Button {
id: btn
background: Item { }
icon.color: "#ffd100"
icon.height: parent.height
icon.width: parent.width
icon.source: "Hex.svg"
}
}
}
//Hex.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-200 -200 400 400">
<path stroke="black" stroke-width="25" stroke-linejoin="round" d="M 100 0 L 50 86.6 L -50 86.6 L -100 0 L -50 -86.6 L 50 -86.6 z" />
</svg>