When building a custom GIS application with QGIS API and Qt, one common requirement is to allow users to control how different layers (roads, rivers, boundaries, towns, etc.) are displayed on the map.
In this article, we’ll walk through how you can implement a GUI that enables users to:
- Show or hide layers
- Change colors for lines, polygons, and points
- Switch line styles (solid, dashed, dotted, etc.)
- Enable/disable fill colors for polygons
This flexibility ensures that your GIS tool is not only functional but also user-friendly for different visualization needs.
Example: Updating Layer Settings
Below is a simplified function that demonstrates how you can implement these controls using QGIS API + Qt Widgets.
We’ll rename our handler to LayerSettings::UpdateMapLayersSettings()
for better readability.
void LayerSettings::UpdateMapLayersSettings()
{
QgsVectorLayer *vectorLayer;
QTableWidgetItem *tablewidgetitem;
for (int row = 0; row < TOTAL_LAYERS_ROW; row++)
{
// Get vector layer for this row
vectorLayer = mDisplayControlLayers.value(row);
if (!vectorLayer || !vectorLayer->isValid())
continue;
// Check if layer visibility is toggled off
tablewidgetitem = ui->tableWidgetMap->item(row, 0);
if (tablewidgetitem->checkState() == Qt::Unchecked)
{
mLayerTreeView->setCurrentLayer(vectorLayer);
mLayerTreeView->currentNode()->setItemVisibilityChecked(false);
vectorLayer->setLabelsEnabled(false);
continue;
}
// If visible → enable
mLayerTreeView->setCurrentLayer(vectorLayer);
mLayerTreeView->currentNode()->setItemVisibilityChecked(true);
QColor strokeColor = Qt::black;
QColor fillColor = Qt::transparent;
bool fillEnabled = false;
// --- Fetch fill option (from checkbox in UI)
QWidget *tablewidget = ui->tableWidgetMap->cellWidget(row, 3);
if (tablewidget != nullptr)
{
QCheckBox *chkbox = tablewidget->findChild<QCheckBox*>();
fillEnabled = (chkbox && chkbox->isChecked());
}
// --- Fetch color (from tool button in UI)
tablewidget = ui->tableWidgetMap->cellWidget(row, 4);
if (tablewidget != nullptr)
{
QToolButton *toolButton = tablewidget->findChild<QToolButton*>();
if (toolButton != nullptr)
{
QStringList colorList = toolButton->styleSheet().split(": ");
if (colorList.size() > 1)
{
QString colorString = colorList[1].trimmed();
colorString.remove(";");
fillColor.setNamedColor(colorString);
strokeColor = fillColor;
}
}
}
// --- Fetch line style (from combo box in UI)
Qt::PenStyle lineStyle = Qt::SolidLine;
tablewidget = ui->tableWidgetMap->cellWidget(row, 5);
if (tablewidget != nullptr)
{
QComboBox *comboBox = tablewidget->findChild<QComboBox*>();
if (comboBox != nullptr)
{
int index = comboBox->currentIndex();
lineStyle = static_cast<Qt::PenStyle>((index + 1) % 6);
}
}
// --- Apply symbols based on geometry type ---
if (vectorLayer->geometryType() == Qgis::GeometryType::Polygon)
{
auto *fillLayer = new QgsSimpleFillSymbolLayer(
fillEnabled ? fillColor : Qt::transparent,
strokeColor,
lineStyle
);
auto *symbol = new QgsFillSymbol();
symbol->changeSymbolLayer(0, std::move(fillLayer));
vectorLayer->setRenderer(new QgsSingleSymbolRenderer(symbol));
}
else if (vectorLayer->geometryType() == Qgis::GeometryType::Line)
{
auto *lineLayer = new QgsSimpleLineSymbolLayer(strokeColor, 0.25, lineStyle);
auto *symbol = new QgsLineSymbol();
symbol->changeSymbolLayer(0, std::move(lineLayer));
vectorLayer->setRenderer(new QgsSingleSymbolRenderer(symbol));
}
else if (vectorLayer->geometryType() == Qgis::GeometryType::Point)
{
auto *markerLayer = new QgsSimpleMarkerSymbolLayer();
markerLayer->setColor(fillColor);
auto *symbol = new QgsMarkerSymbol();
symbol->changeSymbolLayer(0, std::move(markerLayer));
vectorLayer->setRenderer(new QgsSingleSymbolRenderer(symbol));
}
}
// Refresh map canvas after updates
mMapCanvas->refresh();
}
How This Works
- Visibility Control – A
QCheckBox
in the table toggles the visibility of each layer. - Color Picker – A
QToolButton
styled with background color lets the user choose stroke/fill colors. - Line Style – A
QComboBox
provides style options like solid, dashed, dotted, etc. - Geometry Handling – Depending on whether the layer is a polygon, line, or point, we apply the appropriate QGIS symbol renderer.
- Canvas Refresh – Finally, we refresh the map canvas so the user sees immediate changes.
Final Thoughts
By providing such customization options, your GIS application becomes far more interactive and user-centric. Whether you’re displaying roads, rivers, city points, or administrative boundaries, users can style them to suit their analysis needs.
If you’re interested in a full-fledged GIS solution, check out our flagship product PrithviGIS – a powerful QGIS-based platform for real-time geospatial visualization.
📩 For collaboration, demos, or project discussions, feel free to contact Manya Technologies.