### Initialize QuickQanava in C++ Source: http://cneben.github.io/QuickQanava/advanced.html Initialize the QML engine and QuickQanava for rendering topology. This must be done before starting the application event loop. ```cpp // main.cpp int main(int argc, char** argv) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; QuickQanava::initialize(&engine); // Mandatory engine.load(QUrl("qrc:/main.qml")); // Custom "synchronous" topology initialization should be added here return app.exec(); } ``` -------------------------------- ### Install QuickQanava as a Git Submodule Source: http://cneben.github.io/QuickQanava/installation.html Add QuickQanava as a Git submodule to your project for easy integration. ```bash $ git submodule add https://github.com/cneben/QuickQanava * git submodule update ``` -------------------------------- ### QML Structure for C++ Integration Source: http://cneben.github.io/QuickQanava/advanced.html A minimal QuickQanava QML setup to be loaded by the C++ application. It includes the GraphView and a Graph component with a specified objectName. ```qml // main.qml import QuickQanava 2.0 as Qan import "qrc:/QuickQanava" as Qan ApplicationWindow { title: "QuickQanava cpp API" Qan.GraphView { anchors.fill: parent graph : Qan.Graph { objectName: "graph" anchors.fill: parent } // Qan.Graph: graph } } ``` -------------------------------- ### Create and Populate a Qan.Graph in QML Source: http://cneben.github.io/QuickQanava/graph.html Create a `Qan.Graph` component in QML and use the `Component.onCompleted` handler to insert nodes and set their properties. This example demonstrates adding a single node with a label. ```qml Qan.Graph { id: graph anchors.fill: parent Component.onCompleted: { var n1 = graph.insertNode() n1.label = "Hello World" } } ``` -------------------------------- ### Install Custom Node Behaviour in C++ Source: http://cneben.github.io/QuickQanava/advanced.html Install a custom node behavior onto a graph node using the attachBehaviour method. This allows the node to react to topological changes like edge insertions or removals. ```cpp { qan::Graph graph; auto node = graph.insertNode(); node->attachBehaviour(std::make_unique()); // node will now react when an in node is inserted or removed auto source = graph.insertNode(); auto edge = graph.insertEdge(source, node); // CustomBehaviour::Inserted() called graph.removeEdge(edge); // CustomBehaviour::inNodeRemoved() called } ``` -------------------------------- ### Custom Graph Class Implementation Source: http://cneben.github.io/QuickQanava/advanced.html Create a specialized qan::Graph class to manage custom primitives. This example shows how to insert a custom node type. ```cpp // class MyGraph : public qan::Graph ... qan::Node* MyGraph::insertMyNode() noexcept { return insertNode() } ``` -------------------------------- ### Configure Grid Appearance in Qan.GraphView Source: http://cneben.github.io/QuickQanava/graph.html Configure the grid appearance for a `Qan.GraphView` by setting `gridScale`, `gridMajor`, and `gridThickColor` properties. This example uses a `Qan.LineGrid` with specific scale and major line intervals. ```qml import QuickQanava 2.0 as Qan import "qrc:/QuickQanava" as Qan Qan.GraphView { id: graphView anchors.fill: parent graph: Qan.Graph { gridThickColor: "lightgrey" grid: Qan.LineGrid{ gridScale: 50 gridMajor: 5 } } // Qan.Graph: graph } // Qan.GraphView ``` -------------------------------- ### Iterate Selected Nodes in C++ Source: http://cneben.github.io/QuickQanava/nodes.html Shows how to iterate through the currently selected nodes in a Qanava graph using C++. It includes examples for both non-const and const iteration, with null checks for thread safety. ```cpp auto graph = std::make_unique(); for (auto node : graph->getSelectNodes()) { if (node != nullptr) node->doWhateverYouWant(); } // Or better: for (const auto node : qAsConst(graph->getSelectNodes())) { if (node != nullptr) node->doWhateverYouWantConst(); } ``` -------------------------------- ### Build QuickQanava Samples with CMake Source: http://cneben.github.io/QuickQanava/installation.html Manually build QuickQanava samples using CMake, configuring build type and sample building options. ```bash $ cd QuickQanava $ mkdir build $ cd build # IF QT_DIR IS CONFIGURED AND QMAKE IN PATH $ cmake -DCMAKE_BUILD_TYPE=Release -DQUICK_QANAVA_BUILD_SAMPLES=OFF .. # IF QT DIR IS NOT CONFIGURED, CONFIGURE KIT MANUALLY $ cmake -DCMAKE_PREFIX_PATH="/path/to/Qt/5.15.14/gcc_64" -DQT_QMAKE_EXECUTABLE="/path/to/Qt/6.6.1/gcc_64/bin/qmake" -DQUICK_QANAVA_BUILD_SAMPLES=OFF ../QuickQanava/ $ cmake --build . # Then run the samples in ./samples # There is no make install ``` -------------------------------- ### Initialize QuickQanava in C++ Source: http://cneben.github.io/QuickQanava/graph.html Initialize QuickQanava in your C++ main function before loading QML. Ensure `QGuiApplication` and `QQmlApplicationEngine` are set up. ```cpp #include int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQuickStyle::setStyle("Material"); QQmlApplicationEngine engine; // Or in a custom QQuickView constructor: QuickQanava::initialize(); engine.load( ... ); return app.exec(); } ``` -------------------------------- ### Inserting and Configuring Nodes Source: http://cneben.github.io/QuickQanava/nodes.html Demonstrates how to insert a new node, set its label, and position its visual item. ```APIDOC ## Qan.Graph.insertNode() ### Description Inserts a new node into the graph. ### Method `Qan.Graph.insertNode()` ### Endpoint N/A (QML method) ### Parameters None ### Request Example ```javascript var n1 = graph.insertNode() n1.label = "Hello World" n1.item.x = 50 n1.item.y = 50 ``` ### Response #### Success Response Returns the newly created node object. #### Response Example ```javascript // Returns a node object ``` ``` -------------------------------- ### Insert Default Group and Nodes Source: http://cneben.github.io/QuickQanava/nodes.html Demonstrates inserting nodes and a group into the graph, then assigning nodes to the group. Use this to set up initial graph structure with grouped elements. ```qml Qan.Graph { id: graph objectName: "graph" anchors.fill: parent Component.onCompleted: { var n1 = graph.insertNode() n1.label = "N1" var n2 = graph.insertNode() n2.label = "N2" var n3 = graph.insertNode() n3.label = "N3" graph.insertEdge(n1, n2) graph.insertEdge(n2, n3) var gg = graph.insertGroup(); gg.item.preferredGroupWidth = 300. gg.item.preferredGroupHeight = 250. gg.item.minimumGroupWidth = 200. gg.item.minimumGroupHeight = 150. gg.label = "Group" } } // Qan.Graph: graph ``` -------------------------------- ### Inserting Ports Source: http://cneben.github.io/QuickQanava/nodes.html Explains how to insert input and output ports onto a node. ```APIDOC ## Qan.Graph.insertInPort(node, orientation) ### Description Inserts an input port on a specified node at a given orientation. ### Method `Qan.Graph.insertInPort(node, orientation)` ### Endpoint N/A (QML method) ### Parameters - **node** (Qan.Node) - Required - The node to which the port will be added. - **orientation** (enum) - Required - The orientation of the port (e.g., Qan.NodeItem.Left, Qan.NodeItem.Top, Qan.NodeItem.Right, Qan.NodeItem.Bottom). ### Request Example ```javascript var n3 = graph.insertNode() var n3p1 = graph.insertInPort(n3, Qan.NodeItem.Left) n3p1.label = "IN #1" ``` ### Response #### Success Response Returns the newly created `Qan.PortItem` object. #### Response Example ```javascript // Returns a Qan.PortItem object ``` ``` ```APIDOC ## Qan.Graph.insertOutPort(node, orientation) ### Description Inserts an output port on a specified node at a given orientation. ### Method `Qan.Graph.insertOutPort(node, orientation)` ### Endpoint N/A (QML method) ### Parameters - **node** (Qan.Node) - Required - The node to which the port will be added. - **orientation** (enum) - Required - The orientation of the port (e.g., Qan.NodeItem.Left, Qan.NodeItem.Top, Qan.NodeItem.Right, Qan.NodeItem.Bottom). ### Request Example ```javascript var n3 = graph.insertNode() var n3p1 = graph.insertOutPort(n3, Qan.NodeItem.Top) n3p1.label = "OUT #1" ``` ### Response #### Success Response Returns the newly created `Qan.PortItem` object. #### Response Example ```javascript // Returns a Qan.PortItem object ``` ``` -------------------------------- ### Configuring Node Resizing Source: http://cneben.github.io/QuickQanava/nodes.html Explains how to enable/disable node resizing and set the aspect ratio. ```APIDOC ## Qan.NodeItem.resizable ### Description Enables or disables the visual resizing of a node item. ### Method `Qan.NodeItem.resizable` (property) ### Endpoint N/A (QML property) ### Parameters - **resizable** (boolean) - Required - `true` to enable resizing, `false` to disable. ### Request Example ```javascript var n1 = graph.insertNode() n1.item.resizable = false // Disable resizing for n1 var n2 = graph.insertNode() n2.item.resizable = true // Enable resizing for n2 (default behavior) ``` ### Response #### Success Response None #### Response Example None ``` ```APIDOC ## Qan.NodeItem.ratio ### Description Sets the allowed resizing ratio (width/height) for a node item when visual resizing is enabled. If set to a negative value, the ratio is not conserved. ### Method `Qan.NodeItem.ratio` (property) ### Endpoint N/A (QML property) ### Parameters - **ratio** (float) - Required - The desired width/height ratio. Default is -1 (ratio not conserved). ### Request Example ```javascript var n2 = graph.insertNode() n2.item.resizable = true n2.item.ratio = 0.5 // Maintain a width/height ratio of 0.5 ``` ### Response #### Success Response None #### Response Example None ``` -------------------------------- ### Enable Visual Edge Creation Source: http://cneben.github.io/QuickQanava/edges.html Configure Qan.Graph to enable visual node connection. The connectorEdgeInserted signal is emitted upon successful edge creation. ```qml Qan.GraphView { id: graphView anchors.fill: parent graph : Qan.Graph { connectorEnabled: true connectorEdgeInserted: console.debug( "Edge inserted between " + src.label + " and " + dst.label) connectorEdgeColor: "violet" connectorColor: "lightblue" } // Qan.Graph } // Qan.GraphView ``` -------------------------------- ### Import QuickQanava in QML Source: http://cneben.github.io/QuickQanava/graph.html Import the QuickQanava module in your QML files to use its components. Use the specified alias for convenience. ```qml import QuickQanava 2.0 as Qan import "qrc:/QuickQanava" as Qan ``` -------------------------------- ### Integrate QuickQanava with CMake Source: http://cneben.github.io/QuickQanava/installation.html Include QuickQanava in your CMake project by adding its subdirectory and linking necessary libraries. ```cmake add_subdirectory(PATH_TO_QUICKQANAVA_SUBMODULE) target_include_directories(my_project PUBLIC QuickQanava Qt${QT_VERSION_MAJOR}::QuickControls2) target_link_libraries(sample_advanced QuickQanava Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::QuickControls2 ) ``` -------------------------------- ### Apply Material Styling to QuickQanava Graph Source: http://cneben.github.io/QuickQanava/styles.html Bind UI element colors to a Qt Quick Controls 2 theme for light and dark mode support. Ensure Material 2.1 and QuickQanava 2.0 are imported. ```qml import QtQuick.Controls.Material 2.1 import QuickQanava 2.0 as Qan import "qrc:/QuickQanava" as Qan Qan.GraphView { resizeHandlerColor: Material.accent gridThickColor: Material.theme === Material.Dark ? "#4e4e4e" : "#c1c1c1" topology: Qan.Graph { // ... selectionColor: Material.accent connectorColor: Material.accent connectorEdgeColor: Material.accent // ... } // Qan.Graph // ... } // Qan.GraphView ``` -------------------------------- ### Insert Ports and Bind Edges Source: http://cneben.github.io/QuickQanava/nodes.html Insert input and output ports on a node using `graph.insertInPort()` and `graph.insertOutPort()`. Bind edges to these ports using `graph.bindEdgeSource()` and `graph.bindEdgeDestination()` to control connection points. ```qml Component.onCompleted: { // Qan.Graph.Component.onCompleted() var n3 = graph.insertNode() n3.label = "N3"; n3.item.x = 500; n3.item.y = 100 var n3p1 = graph.insertInPort(n3, Qan.NodeItem.Left); n3p1.label = "IN #1" var n3p1 = graph.insertInPort(n3, Qan.NodeItem.Top); n3p1.label = "OUT #1" var n3p2 = graph.insertInPort(n3, Qan.NodeItem.Bottom); n3p2.label = "OUT #2" var e = graph.insertEdge(n2, n3) graph.bindEdgeDestination(e, n2p3) // Bind our edge source to node N2 port P3 (OUT #1) graph.bindEdgeDestination(e, n3p1) // Bind our edge destination to node N3 port P1 (IN #1) } ``` -------------------------------- ### Insert and Configure a Node Source: http://cneben.github.io/QuickQanava/nodes.html Use `Qan.Graph.insertNode()` to add a new node to the graph. Set its label and visual position using `n1.label` and `n1.item.x`/`n1.item.y` respectively. The `item` property accesses the node's visual counterpart. ```qml Qan.Graph { id: graph anchors.fill: parent Component.onCompleted: { var n1 = graph.insertNode() n1.label = "Hello World" // n1 encode node topology (it's a qan::Node) n1.item.x = 50; n1.item.y = 50 // n1.item is n1 visual counterpart, usually a qan::NodeItem } } ``` -------------------------------- ### Accessing Qan.Graph from C++ Source: http://cneben.github.io/QuickQanava/advanced.html Find and cast the QML Graph component to its C++ virtual interface (qan::Graph) after the QML engine has loaded the main QML file. ```cpp QPointer graph = nullptr; for (const auto rootObject : engine.rootObjects()) { graph = qobject_cast(rootObject->findChild( ``` ```cpp "graph")); if (graph) break; } if (graph) { // Go on } ``` -------------------------------- ### Configure Node Resizing Source: http://cneben.github.io/QuickQanava/nodes.html Control node resizing behavior by setting the `resizable` property to `false` to disable it, or `true` to enable it (default). Use the `ratio` property to maintain a specific width/height aspect ratio during resizing. ```qml Component.onCompleted: { // Qan.Graph.Component.onCompleted() var n1 = graph.insertNode() n1.item.resizable = false // n1 is not resizable var n2 = graph.insertNode() n2.item.resizable = true // n2 is resizable (setting to true is // not mandatory, it's the default behaviour) n2.item.ratio = 0.5 // node resizing will maintain a width/height ratio // of 0.5, ie height will alays be half of width. } ``` -------------------------------- ### Binding Edges to Ports Source: http://cneben.github.io/QuickQanava/nodes.html Details how to bind an edge's source or destination to a specific port. ```APIDOC ## Qan.Graph.bindEdgeDestination(edge, port) ### Description Binds the destination of an edge to a specific port. ### Method `Qan.Graph.bindEdgeDestination(edge, port)` ### Endpoint N/A (QML method) ### Parameters - **edge** (Qan.Edge) - Required - The edge to bind. - **port** (Qan.PortItem) - Required - The destination port. ### Request Example ```javascript var e = graph.insertEdge(n2, n3) graph.bindEdgeDestination(e, n3p1) // Bind edge destination to node N3 port P1 ``` ### Response #### Success Response None #### Response Example None ``` ```APIDOC ## Qan.Graph.bindEdgeSource(edge, port) ### Description Binds the source of an edge to a specific port. ### Method `Qan.Graph.bindEdgeSource(edge, port)` ### Endpoint N/A (QML method) ### Parameters - **edge** (Qan.Edge) - Required - The edge to bind. - **port** (Qan.PortItem) - Required - The source port. ### Request Example ```javascript var e = graph.insertEdge(n2, n3) graph.bindEdgeSource(e, n2p3) // Bind edge source to node N2 port P3 ``` ### Response #### Success Response None #### Response Example None ``` -------------------------------- ### Create and Style Edges Programmatically Source: http://cneben.github.io/QuickQanava/edges.html Use this snippet within a QML Component.onCompleted handler to programmatically insert nodes and edges, and set default edge styles. ```qml Component.onCompleted: { // Qan.Graph.Component.onCompleted() var n1 = graph.insertNode() n1.label = "Hello World"; n1.item.x=50; n1.item.y= 50 var n2 = graph.insertNode() n2.label = "Node 2"; n2.item.x=200; n2.item.y= 125 var e = graph.insertEdge(n1, n2); defaultEdgeStyle.lineType = Qan.EdgeStyle.Curved } ``` -------------------------------- ### View Selected Nodes with QML ListView Source: http://cneben.github.io/QuickQanava/nodes.html Demonstrates how to display currently selected nodes from a Qanava graph using a QML ListView. The 'selectedNodes' property of the graph is used as the model. ```qml ListView { id: selectionListView Layout.fillWidth: true; Layout.fillHeight: true clip: true model: graph.selectedNodes // <--------- spacing: 4; focus: true; flickableDirection : Flickable.VerticalFlick highlightFollowsCurrentItem: false highlight: Rectangle { x: 0; y: ( selectionListView.currentItem !== null ? selectionListView.currentItem.y : 0 ); width: selectionListView.width; height: selectionListView.currentItem.height color: "lightsteelblue"; opacity: 0.7; radius: 5 } delegate: Item { id: selectedNodeDelegate width: ListView.view.width; height: 30; Text { text: "Label: " + itemData.label } // <----- itemData is a Qan.Node, node // label could be accessed directly MouseArea { anchors.fill: selectedNodeDelegate onClicked: { selectedNodeDelegate.ListView.view.currentIndex = index } } } } ``` -------------------------------- ### Define Custom Node Behaviour in C++ Source: http://cneben.github.io/QuickQanava/advanced.html Define a custom node behavior by inheriting from qan::NodeBehaviour and overriding methods like inNodeInserted and inNodeRemoved. Ensure proper constructor and destructor implementation. ```cpp #include class CustomBehaviour : public qan::NodeBehaviour { Q_OBJECT public: explicit NodeBehaviour(QObject* parent = nullptr) : qan::NodeBehaviour{"Custom Behaviour", parent} { } virtual ~NodeBehaviour() override { /* Nil */ } NodeBehaviour(const NodeBehaviour&) = delete; protected: virtual void inNodeInserted(qan::Node& inNode, qan::Edge& edge) noexcept override; virtual void inNodeRemoved(qan::Node& inNode, qan::Edge& edge) noexcept override; }; ``` -------------------------------- ### Register and Use BottomRightResizer in QML Source: http://cneben.github.io/QuickQanava/utilities.html Register the BottomRightResizer component in C++ and then use it in QML to add a resize handler to a target QML item. This resizer can be used independently of QuickQanava. ```cpp qmlRegisterType("YourModule", 1, 0, "BottomRightResizer"); ``` ```qml import YourModule 1.0 as Qan Item { id: targetItem Qan.BottomRightResizer { target: targetItem } } ``` -------------------------------- ### Custom Node Definition in C++ Source: http://cneben.github.io/QuickQanava/advanced.html Define a custom node class inheriting from qan::Node. This involves overriding delegate and style methods to provide custom QML components and default styles. ```cpp // In a custom MyNode.cpp defining MyNode (inheriting from qan::Node) QQmlComponent* MyNode::delegate(QQmlEngine& engine) noexcept { static std::unique_ptr MyNode_delegate; if (!MyNode_delegate) CustomRectNode_delegate = std::make_unique(&engine, "qrc:/MyNode.qml"); return CustomRectNode_delegate.get(); } qan::NodeStyle* MyNode::style() noexcept { static std::unique_ptr MyNode_style; if (!MyNode_style) { MyNode_style = std::make_unique(); MyNode_style->setBackColor(QColor("#ff29fc")); // Initialize primitive default style here } return MyNode_style.get(); } ``` -------------------------------- ### Custom Edge Creation via Connector Source: http://cneben.github.io/QuickQanava/edges.html Disable default edge creation to emit connectorRequestEdgeCreation signal, allowing custom edge creation logic. This is useful for advanced graph interactions. ```qml Qan.GraphView { id: graphView anchors.fill: parent graph : Qan.Graph { id: graph connectorEnabled: true connectorCreateDefaultEdge: false onConnectorRequestEdgeCreation: { // Do whatever you want here, for example: graph.insertEdge(src, dst) } } // Qan.Graph } // Qan.GraphView ``` -------------------------------- ### Embed Qan.Graph in Qan.GraphView Source: http://cneben.github.io/QuickQanava/graph.html Embed a `Qan.Graph` component within a `Qan.GraphView` to enable user interaction like panning and zooming. The `graph` property of `Qan.GraphView` binds it to the topology. ```qml Qan.GraphView { id: graphView anchors.fill: parent navigable : true graph: Qan.Graph { id: topology } // Qan.Graph: topology } // Qan.GraphView ``` -------------------------------- ### Removing Nodes Source: http://cneben.github.io/QuickQanava/nodes.html Details the method for removing a node from the graph. ```APIDOC ## Qan.Graph.removeNode() ### Description Removes a node from the graph. ### Method `Qan.Graph.removeNode()` ### Endpoint N/A (QML method) ### Parameters - **node** (Qan.Node) - Required - The node to remove. ### Request Example ```javascript // Assuming 'nodeToRemove' is a variable holding the node object graph.removeNode(nodeToRemove) ``` ### Response #### Success Response None #### Response Example None ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.