Hello,
I could change the position arrow color with a plugin but
Is it possible to change the border color of the position arrow?
?
Hello,
I could change the position arrow color with a plugin but
Is it possible to change the border color of the position arrow?
I believe it’s hardcoded to white here: QField/src/qml/LocationMarker.qml at 3adcfd5662d843d2cd13a4a6cd439c53baad5dbe · opengisch/QField · GitHub
So, I don’t think you can change it, unless you walk down children manually (which I would not recommend), and set the value there directly.
Thanks,
perhaps i would be themable in a future version
It’ll be available in the next version of QField to be released by the end of the year. See Allow for the location marker border/stroke color to be customized by nirvn · Pull Request #6723 · opengisch/QField · GitHub
Someone knows how i can change the border color of the position point/arrow in 4.0 QField version?
The pull request added the strokeColor attribute to src/qml/LocationMarker.qml. Setting the attribute should result in the expected color change.
I’ve seen this but location marker is not the same than position arrow or i misunderstand something ?
Could you help me Pascal because here i dont know how change boder color of arrow icon position
Oh, you are right, that is odd…
I just assumed it has an object name since the pull request specifically added the attribute to make it adjustable. ![]()
I’ll check if I can find a solution later today.
@Mathieu_Pellerin Sorry for the ping, but maybe you can help us here. Since it’s supposed to be supported now, what would be the recommended way to access this?
QfButton {
id: button
Layout.fillWidth: true
text: "Button"
visible: true
onClicked: {
var mapCanvas = iface.findItemByObjectName('mapCanvasContainer');
if (mapCanvas) {
var locationMarker = findLocationMarker(mapCanvas);
if (locationMarker) {
locationMarker.strokeColor = Qt.rgba(1, 0, 0, 1);
locationMarker.color = Qt.rgba(1, 0, 0, 1);
}
}
}
function findLocationMarker(parent) {
for (var i = 0; i < parent.children.length; i++) {
var child = parent.children[i];
if (child.toString().indexOf("LocationMarker") !== -1) {
return child;
}
}
return null;
}
}
Does this work for you? I only had the chance to test it with the dot marker, not the arrow, and there it changes the color, but not the stroke color (QField 4.0.0 Windows)
I feel like it should work ![]()
Thank you Pascal
I test it and it change color and stroke color on arrow but not stroke color on dot
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Item {
id: root
Component.onCompleted: {
iface.addItemToPluginsToolbar(pluginButton)
}
Button {
id: pluginButton
text: "Rouge"
contentItem: Text {
text: pluginButton.text
color: "white"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.bold: true
}
background: Rectangle {
implicitWidth: 60
implicitHeight: 40
color: pluginButton.pressed ? "#d32f2f" : "#f44336" // Rouge
radius: 4
}
onClicked: {
var mapCanvas = iface.findItemByObjectName('mapCanvasContainer');
if (mapCanvas) {
var locationMarker = findLocationMarker(mapCanvas);
if (locationMarker) {
locationMarker.strokeColor = Qt.rgba(1, 0, 0, 1);
locationMarker.color = Qt.rgba(1, 0, 0, 1);
iface.mainWindow().displayToast("Marqueur passé en rouge");
} else {
iface.mainWindow().displayToast("Activer le GPS d'abord !");
}
}
}
function findLocationMarker(parent) {
for (var i = 0; i < parent.children.length; i++) {
var child = parent.children[i];
if (child.toString().indexOf("LocationMarker") !== -1) {
return child;
}
var grandChild = findLocationMarker(child);
if (grandChild) return grandChild;
}
return null;
}
}
}
Another plugin code that will remenber you something and with locationmarker integration
import QtQuick
import QtCore
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import org.qfield
import org.qgis
import Theme
import “.”
Item {
id: plugin
property var mainWindow: iface.mainWindow()
// --- 0. SYSTÈME DE TRADUCTION ---
property string currentLang: Qt.locale().name.substring(0, 2)
property var translations: {
"pos_point": { "en": "Pos. (Point)", "fr": "Pos. (Point)" },
"center_pt": { "en": "Center point", "fr": "Point central" },
"pos_bg": { "en": "Pos. (Backgr.)", "fr": "Pos. (Fond)" },
"white_halo": { "en": "White halo", "fr": "Halo blanc" },
"acc_high": { "en": "Acc. (High)", "fr": "Préc. (Top)" },
"green_circ": { "en": "Green circle", "fr": "Cercle vert" },
"acc_avg": { "en": "Acc. (Avg.)", "fr": "Préc. (Moy.)" },
"orange_circ": { "en": "Orange circle", "fr": "Cercle orange" },
"acc_low": { "en": "Acc. (Low)", "fr": "Préc. (Mauv.)" },
"red_circ": { "en": "Red circle", "fr": "Cercle rouge" },
"gps_colors": { "en": "GPS Colors", "fr": "Couleurs GPS" },
"pos_tint": { "en": "Position Tint", "fr": "Teinte Position" },
"reset": { "en": "Reset", "fr": "Réinitialiser" },
"apply": { "en": "Apply", "fr": "Appliquer" }
}
function tr(key) {
var t = translations[key];
if (t) return (currentLang === "fr") ? t.fr : t.en;
return key;
}
// --- 1. CONFIGURATION ---
property var positionColorConfig: ({
"positionColor": { "name": tr("pos_point"), "desc": tr("center_pt") },
"positionBackgroundColor": { "name": tr("pos_bg"), "desc": tr("white_halo") },
"accuracyExcellent": { "name": tr("acc_high"), "desc": tr("green_circ") },
"accuracyTolerated": { "name": tr("acc_avg"), "desc": tr("orange_circ") },
"accuracyBad": { "name": tr("acc_low"), "desc": tr("red_circ") }
})
property var defaultColors: ({
"positionColor": "#3388FF",
"positionBackgroundColor": "#FFFFFF",
"accuracyExcellent": "#4CAF50",
"accuracyTolerated": "#FF9800",
"accuracyBad": "#F44336"
})
property var colorKeys: Object.keys(positionColorConfig)
// --- 2. SAUVEGARDE ---
Settings {
id: themeSettings
property string jsonColors: "{}"
}
// --- 3. FONCTIONS POUR LE MARQUEUR (AJOUTÉ) ---
function findLocationMarker(parent) {
if (!parent || !parent.children) return null;
for (var i = 0; i < parent.children.length; i++) {
var child = parent.children[i];
if (child.toString().indexOf("LocationMarker") !== -1) return child;
var res = findLocationMarker(child);
if (res) return res;
}
return null;
}
function updateLiveMarker(key, hexValue) {
if (key !== "positionColor") return; // On ne change le marqueur que pour la couleur centrale
var mapCanvas = iface.findItemByObjectName('mapCanvasContainer');
if (mapCanvas) {
var marker = findLocationMarker(mapCanvas);
if (marker) {
marker.strokeColor = hexValue;
marker.color = hexValue;
}
}
}
// --- 4. FONCTION D'APPLICATION ---
function applyColorChange(key, hexValue) {
try {
if (key === undefined || key === "") return;
var currentJson = themeSettings.jsonColors || "{}";
var colorsObj = JSON.parse(currentJson);
colorsObj[key] = hexValue;
Theme.applyColors(colorsObj);
// Intégration du changement de couleur en direct
updateLiveMarker(key, hexValue);
themeSettings.jsonColors = JSON.stringify(colorsObj);
} catch (e) {
console.log("Erreur application couleur: " + e);
}
}
// --- 5. BOUTON TOOLBAR ---
QfToolButton {
id: openColorsBtn
iconSource: 'icon.svg'
iconColor: Theme.mainColor
bgcolor: Theme.darkGray
round: true
ToolTip.visible: pressed
ToolTip.text: plugin.tr("gps_colors")
onClicked: positionColorDialog.open()
}
// --- 6. DIALOGUE ---
Dialog {
id: positionColorDialog
modal: true
visible: false
parent: plugin.mainWindow.contentItem
anchors.centerIn: parent
width: Math.min(500, parent.width * 0.95)
background: Rectangle {
color: Theme.mainBackgroundColor
radius: 8
border.color: Theme.mainColor
border.width: 2
}
contentItem: ColumnLayout {
id: mainLayout
spacing: 10
Label {
text: plugin.tr("pos_tint")
font.bold: true; font.pixelSize: 18
color: Theme.mainTextColor
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 10
Layout.bottomMargin: 5
}
ScrollView {
id: listScrollView
Layout.fillWidth: true
Layout.preferredHeight: Math.min(listContent.implicitHeight, plugin.mainWindow.height * 0.6)
clip: true
GridLayout {
id: listContent
width: listScrollView.availableWidth
columns: 2
columnSpacing: 10; rowSpacing: 10
Repeater {
model: plugin.colorKeys
delegate: Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 64
color: "transparent"
border.color: Theme.controlBorderColor; border.width: 1; radius: 6
property string currentKey: modelData
property var itemConfig: plugin.positionColorConfig[modelData]
property string displayColor: {
var c = Theme[modelData];
return c ? c.toString() : "#000000";
}
// Zone de clic pour ouvrir le dialogue
MouseArea {
anchors.fill: parent
onClicked: colorPicker.open()
}
RowLayout {
anchors.fill: parent
anchors.margins: 6; spacing: 8
Rectangle {
width: 24; height: 24; radius: 12
color: displayColor
border.color: Theme.controlBorderColor; border.width: 1
}
ColumnLayout {
Layout.fillWidth: true; spacing: 0
Label {
text: itemConfig.name; font.bold: true; font.pixelSize: 12
color: Theme.mainTextColor; elide: Text.ElideRight; Layout.fillWidth: true
}
Label {
text: itemConfig.desc; font.pixelSize: 10
color: Theme.secondaryTextColor; elide: Text.ElideRight; Layout.fillWidth: true
}
}
Button {
display: AbstractButton.IconOnly
icon.source: "palette_icon.svg"
icon.color: Theme.mainTextColor; icon.width: 30; icon.height: 30
Layout.preferredWidth: 40; Layout.preferredHeight: 40
background: Rectangle {
color: parent.down ? Theme.controlBackgroundColor : "transparent"
radius: 4
}
onClicked: colorPicker.open()
}
}
// LE DIALOGUE DE COULEUR (Votre structure exacte)
ColorDialog {
id: colorPicker
title: itemConfig.name
selectedColor: displayColor
options: ColorDialog.ShowAlphaChannel
onAccepted: {
var colorString = "" + selectedColor;
plugin.applyColorChange(currentKey, colorString);
}
}
}
}
}
}
RowLayout {
Layout.fillWidth: true; Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 5; Layout.bottomMargin: 10; spacing: 20
Button {
text: plugin.tr("reset")
onClicked: {
themeSettings.jsonColors = "{}";
Theme.applyColors(plugin.defaultColors);
// On réinitialise aussi le marqueur en direct
plugin.updateLiveMarker("positionColor", plugin.defaultColors.positionColor);
}
}
Button {
text: plugin.tr("apply")
highlighted: true
onClicked: positionColorDialog.close()
}
}
}
}
Component.onCompleted: {
iface.addItemToPluginsToolbar(openColorsBtn);
loadTimer.start();
}
Timer {
id: loadTimer
interval: 1000
onTriggered: {
try {
var c = JSON.parse(themeSettings.jsonColors || "{}");
if(Object.keys(c).length > 0) {
Theme.applyColors(c);
if (c.positionColor) plugin.updateLiveMarker("positionColor", c.positionColor);
}
} catch(e) {}
}
}
}
To change dot border color, you need to play with borderColor
I can change border witdth for dot but @Mathieu_Pellerin could you let us, when you will have some free time, to change arrow border too, please
Sorry for this ping in christmas holidays…
For those who are interested, you can customize size and colors