Ich entwickle eine GIS-bezogene Anwendung, in der ich eine Karte habe, und ich möchte Kreise darauf setzen. Dafür benutze ich QML. Die Architektur lautet: < /p>
1-GeometrikFigur.H: Grenzfläche für gemeinsame geometrische Figuren < /p>
2- Kreis.H und Kreis.CPP: Subklassen von Geometrieb und Geometricform.H und GEOMETRICRICRICN. QabstractListModel zum Speichern der auf der Karte gezeichneten geometrischen Figuren < /strong>. Ich möchte, dass mein C ++-Klassenkreis eine visuelle Darstellung hat, nicht nur für die Backend-Verarbeitung.// main.cpp
#include
#include
#include "Circle.h"
#include "GeometricFigureList.h"
#include
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
// Register circle class for use in QML
qmlRegisterType("MiApp.Figures", 1, 0, "Circle");
// Register model
ListaFigurasGeometricas figureList;
engine.rootContext()->setContextProperty("figureList", &figureList);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("Test", "Main");
return app.exec();
}
< /code>
// Main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtLocation 6.8
import QtPositioning 6.8
import MiApp.Figures 1.0
import "./" // Importa los componentes CircleElement, etc.
Window {
width: 800
height: 600
visible: true
title: qsTr("Map with elements")
// Propiedad para almacenar el tipo de elemento seleccionado:
property string currentElementType: "circle" // Valor por defecto
Column {
anchors.fill: parent
// Fila con botones para seleccionar el tipo de elemento
Row {
spacing: 10
padding: 10
Button {
text: "Circle"
onClicked: currentElementType = "circle"
}
}
// MapView que muestra el mapa y donde se crearán los elementos
MapView {
id: mapView
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: parent.height - 60
map.plugin: Plugin { name: "osm" }
map.center: QtPositioning.coordinate(40.416775, -3.703790)
map.zoomLevel: 10
// Capturamos el click en el mapa para crear el elemento seleccionado.
MouseArea {
anchors.fill: parent
onClicked: function(mouseEvent) {
var coord = mapView.map.toCoordinate(Qt.point(mouseEvent.x, mouseEvent.y))
// Aquí creas el objeto dinámicamente, etc.
// Crear dinámicamente el elemento en el mapa.
if (currentElementType === "circle") {
var cir = circleComponent.createObject(mapView.map,{radius:100000, center:coord})
mapView.map.addMapItem(cir)
figureList.addData(cir.getInternalCircle())
}
}
}
}
}
// Componentes para instanciar dinámicamente cada tipo de elemento
Component {
id: circleComponent
Circle {
}
}
}
< /code>
// Circle.qml
import QtQuick 2.15
import QtLocation 6.8
import QtPositioning 6.8
import MiApp.Figures 1.0
MapCircle{
id: myWrapper
color: "red"
// Si usase circle directamente, QML no sabría como pintarlo
// He de tener un wrapper, MapCircle, para poder usarlo.
Circle{
id: myCircle
}
function getInternalCircle(){
myCircle.setRadius(myWrapper.radius)
myCircle.setCenter(myWrapper.center)
return myCircle
}
onRadiusChanged: myCircle.setRadius(myWrapper.radius)
onCenterChanged: myCircle.setCenter(myWrapper.center)
}
< /code>
//GeometricFigureList.cpp
#include "GeometricFigureList.h"
GeometricFigureList::GeometricFigureList(QObject *parent)
: QAbstractListModel(parent) {}
int GeometricFigureList::rowCount(const QModelIndex &parent) const {
Q_UNUSED(parent)
return m_list.size();
}
QVariant GeometricFigureList::data(const QModelIndex &index, int role) const {
if (!index.isValid() || index.row() >= m_list.size())
return QVariant();
const GeometricFigures *figure = m_list.at(index.row());
if (role == NombreRole)
return figure->name();
else if (role == TipoRole)
return figure->tipo();
return QVariant();
}
bool GeometricFigureList::setData(const QModelIndex &index, const QVariant &value, int role) {
if (!index.isValid() || index.row() >= m_list.size())
return false;
GeometricFigures *figure = m_list.at(index.row());
if (role == NombreRole)
figure->setName(value.toString());
else if (role == TipoRole)
figure->setType(value.toInt());
else
return false;
emit dataChanged(index, index, {role});
return true;
}
void GeometricFigureList::addData(GeometricFigures *figure) {
beginInsertRows(QModelIndex(), m_list.size(), m_list.size());
m_list.append(figure);
endInsertRows();
}
QHash GeometricFigureList::roleNames() const {
QHash roles;
roles[NombreRole] = "name";
roles[TipoRole] = "tipo";
return roles;
}
< /code>
#ifndef GEOMETRICFIGURELIST_H
#define GEOMETRICFIGURELIST_H
#include
#include "GeometricFigures.h"
class GeometricFigureList : public QAbstractListModel {
Q_OBJECT
public:
explicit GeometricFigureList(QObject *parent = nullptr);
enum Roles {
NombreRole = Qt::UserRole + 1,
TipoRole
};
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
Q_INVOKABLE void addData(GeometricFigures *figure);
QHash roleNames() const override;
private:
QList m_list;
};
#endif // LISTAFIGURASGEOMETRICAS_H
< /code>
//Circle.cpp
#include "Circle.h"
Circle::Circle(QQuickItem *parent) : GeometricFigures(parent), m_radio(0.0) {}
double Circle::radio() const { return m_radio; }
void Circle::setRadius(double r) {
if (m_radio != r) {
m_radio = r;
emit radioChanged();
}
}
QGeoCoordinate Circle::center() const{
return m_center;
}
void Circle::setCenter(QGeoCoordinate c){
m_center = c;
}
QString Circle::name() const { return "Circle"; }
void Circle::setName(const QString &) {}
int Circle::tipo() const { return 1; }
void Circle::setType(int) {}
< /code>
#ifndef CIRCLE_H
#define CIRCLE_H
#include "GeometricFigures.h"
#include
class Circle : public GeometricFigures {
Q_OBJECT
Q_PROPERTY(double radio READ radio WRITE setRadius NOTIFY radioChanged)
Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged)
public:
explicit Circle(QQuickItem *parent = nullptr);
Q_INVOKABLE double radio() const;
Q_INVOKABLE void setRadius(double r);
Q_INVOKABLE QGeoCoordinate center() const;
Q_INVOKABLE void setCenter(QGeoCoordinate r);
QString name() const override;
void setName(const QString &) override ;
int tipo() const override;
void setType(int) override;
signals:
void radioChanged();
void centerChanged();
private:
double m_radio;
QGeoCoordinate m_center;
};
#endif // CIRCLE_H
< /code>
#ifndef FIGURASGEOMETRICAS_H
#define FIGURASGEOMETRICAS_H
#include
#include
class GeometricFigures : public QQuickItem {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(int tipo READ tipo WRITE setType NOTIFY typeChanged)
public:
explicit GeometricFigures(QQuickItem *parent = nullptr) : QQuickItem (parent) {}
virtual QString name() const = 0;
virtual void setName(const QString &) = 0;
virtual int tipo() const = 0;
virtual void setType(int) = 0;
signals:
void nameChanged();
void typeChanged();
};
#endif // FIGURASGEOMETRICAS_H
< /code>
cmake_minimum_required(VERSION 3.16)
project(Test VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Quick Positioning)
qt_standard_project_setup(REQUIRES 6.8)
qt_add_executable(appTest
main.cpp
)
qt_add_qml_module(appTest
URI Test
VERSION 1.0
QML_FILES
Main.qml
QML_FILES Circle.qml
SOURCES GeometricFigures.h
SOURCES Circle.h Circle.cpp
SOURCES GeometricFigureList.h GeometricFigureList.cpp
)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(appTest PROPERTIES
# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appTest
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
target_link_libraries(appTest
PRIVATE Qt6::Quick
PRIVATE Qt6::Positioning
)
include(GNUInstallDirs)
install(TARGETS appTest
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
< /code>
The problem with that is that I have to use MapCircle as a wrapper and I want a solution more like:
Circle{
id: myCircle
delegate: MapCircle{
id: myCircleVisualRepresentation
color: "red"
}
}
< /code>
That way I could do:
var cir = circleComponent.createObject(mapView.map)
cir.setRadius(10000)
cir.setCenter(coords)
mapView.map.addMapItem(cir)
figureList.addData(cir)
< /code>
Without requesting the wrapper inner component.
But that is not possible, there is no delegate property in the registered version of Circle class.
So the question is: Is there any way to give C++ registered classes a visual representation in QML?
Thanks and pardon my english.
Gibt es eine Möglichkeit, Klassen in C ++ eine direkte visuelle Darstellung in QML zu geben? ⇐ C++
-
- Similar Topics
- Replies
- Views
- Last post