Skip to content

Commit d407e57

Browse files
committed
Add qml support
Add calculator_test to test a QML form that integrate node editor
1 parent 8b054bc commit d407e57

27 files changed

+1214
-0
lines changed

CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ else()
5656
endif()
5757

5858
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Gui OpenGL)
59+
find_package(Qt${QT_VERSION_MAJOR} QUIET COMPONENTS Quick)
5960
message(STATUS "QT_VERSION: ${QT_VERSION}, QT_DIR: ${QT_DIR}")
6061

6162
if (${QT_VERSION} VERSION_LESS 5.11.0)
@@ -129,6 +130,12 @@ set(HPP_HEADER_FILES
129130
include/QtNodes/internal/UndoCommands.hpp
130131
)
131132

133+
if(Qt${QT_VERSION_MAJOR}Quick_FOUND AND ${QT_VERSION} VERSION_GREATER_EQUAL 6.0.0)
134+
message(STATUS "Qt Quick found")
135+
list(APPEND CPP_SOURCE_FILES src/QmlWrapper.cpp)
136+
list(APPEND HPP_HEADER_FILES include/QtNodes/internal/QmlWrapper.hpp)
137+
endif()
138+
132139
# If we want to give the option to build a static library,
133140
# set BUILD_SHARED_LIBS option to OFF
134141
add_library(QtNodes
@@ -155,6 +162,12 @@ target_link_libraries(QtNodes
155162
Qt${QT_VERSION_MAJOR}::Gui
156163
Qt${QT_VERSION_MAJOR}::OpenGL
157164
)
165+
if(Qt${QT_VERSION_MAJOR}Quick_FOUND AND ${QT_VERSION} VERSION_GREATER_EQUAL 6.0.0)
166+
target_link_libraries(QtNodes
167+
PUBLIC
168+
Qt${QT_VERSION_MAJOR}::Quick
169+
)
170+
endif()
158171

159172
target_compile_definitions(QtNodes
160173
PUBLIC

examples/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ add_subdirectory(dynamic_ports)
1616

1717
add_subdirectory(lock_nodes_and_connections)
1818

19+
if(Qt${QT_VERSION_MAJOR}Quick_FOUND AND ${QT_VERSION} VERSION_GREATER_EQUAL 6.0.0)
20+
add_subdirectory(calculator_qml)
21+
endif()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include "DecimalData.hpp"
4+
#include "MathOperationDataModel.hpp"
5+
6+
#include <QtNodes/NodeDelegateModel>
7+
8+
#include <QtCore/QObject>
9+
#include <QtWidgets/QLabel>
10+
11+
/// The model dictates the number of inputs and outputs for the Node.
12+
/// In this example it has no logic.
13+
class AdditionModel : public MathOperationDataModel
14+
{
15+
public:
16+
~AdditionModel() = default;
17+
18+
public:
19+
QString caption() const override { return QStringLiteral("Addition"); }
20+
21+
QString name() const override { return QStringLiteral("Addition"); }
22+
23+
private:
24+
void compute() override
25+
{
26+
PortIndex const outPortIndex = 0;
27+
28+
auto n1 = _number1.lock();
29+
auto n2 = _number2.lock();
30+
31+
if (n1 && n2) {
32+
_result = std::make_shared<DecimalData>(n1->number() + n2->number());
33+
} else {
34+
_result.reset();
35+
}
36+
37+
Q_EMIT dataUpdated(outPortIndex);
38+
}
39+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
set(CALC_SOURCE_FILES
2+
main.cpp MathOperationDataModel.cpp MyNodeEditor.cpp NumberDisplayDataModel.cpp
3+
NumberSourceDataModel.cpp StringDataModel.cpp)
4+
5+
set(CALC_HEADER_FILES
6+
AdditionModel.hpp
7+
DivisionModel.hpp
8+
DecimalData.hpp
9+
MathOperationDataModel.hpp
10+
MultiplicationModel.hpp
11+
MyNodeEditor.hpp
12+
NumberDisplayDataModel.hpp
13+
NumberSourceDataModel.hpp
14+
SubtractionModel.hpp
15+
StringDataModel.hpp
16+
StringData.hpp)
17+
18+
set(CMAKE_AUTORCC ON)
19+
set(CMAKE_AUTOMOC ON)
20+
set(CMAKE_AUTOUIC ON)
21+
cmake_policy(SET CMP0071 NEW)
22+
23+
qt_standard_project_setup(REQUIRES 6.5)
24+
25+
qt_add_resources(QT_RESOURCES "main.qrc")
26+
qt_add_executable(calculator_qml ${CALC_SOURCE_FILES} ${CALC_HEADER_FILES}
27+
${QT_RESOURCES})
28+
29+
qt_add_qml_module(
30+
calculator_qml VERSION 1.0 URI hello QML_FILES main.qml
31+
)
32+
33+
target_link_libraries(calculator_qml PRIVATE Qt6::Gui QtNodes)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include <QtNodes/NodeData>
4+
5+
using QtNodes::NodeData;
6+
using QtNodes::NodeDataType;
7+
8+
/// The class can potentially incapsulate any user data which
9+
/// need to be transferred within the Node Editor graph
10+
class DecimalData : public NodeData
11+
{
12+
public:
13+
DecimalData()
14+
: _number(0.0)
15+
{}
16+
17+
DecimalData(double const number)
18+
: _number(number)
19+
{}
20+
21+
NodeDataType type() const override { return NodeDataType{"decimal", "Decimal"}; }
22+
23+
double number() const { return _number; }
24+
25+
QString numberAsText() const { return QString::number(_number, 'f'); }
26+
27+
private:
28+
double _number;
29+
};
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#pragma once
2+
3+
#include "DecimalData.hpp"
4+
#include "MathOperationDataModel.hpp"
5+
6+
#include <QtNodes/NodeDelegateModel>
7+
8+
#include <QtCore/QObject>
9+
#include <QtWidgets/QLabel>
10+
11+
/// The model dictates the number of inputs and outputs for the Node.
12+
/// In this example it has no logic.
13+
class DivisionModel : public MathOperationDataModel
14+
{
15+
public:
16+
virtual ~DivisionModel() {}
17+
18+
public:
19+
QString caption() const override { return QStringLiteral("Division"); }
20+
21+
bool portCaptionVisible(PortType portType, PortIndex portIndex) const override
22+
{
23+
Q_UNUSED(portType);
24+
Q_UNUSED(portIndex);
25+
return true;
26+
}
27+
28+
QString portCaption(PortType portType, PortIndex portIndex) const override
29+
{
30+
switch (portType) {
31+
case PortType::In:
32+
if (portIndex == 0)
33+
return QStringLiteral("Dividend");
34+
else if (portIndex == 1)
35+
return QStringLiteral("Divisor");
36+
37+
break;
38+
39+
case PortType::Out:
40+
return QStringLiteral("Result");
41+
42+
default:
43+
break;
44+
}
45+
return QString();
46+
}
47+
48+
QString name() const override { return QStringLiteral("Division"); }
49+
50+
private:
51+
void compute() override
52+
{
53+
PortIndex const outPortIndex = 0;
54+
55+
auto n1 = _number1.lock();
56+
auto n2 = _number2.lock();
57+
58+
if (n2 && (n2->number() == 0.0)) {
59+
//modelValidationState = NodeValidationState::Error;
60+
//modelValidationError = QStringLiteral("Division by zero error");
61+
_result.reset();
62+
} else if (n1 && n2) {
63+
//modelValidationState = NodeValidationState::Valid;
64+
//modelValidationError = QString();
65+
_result = std::make_shared<DecimalData>(n1->number() / n2->number());
66+
} else {
67+
//modelValidationState = NodeValidationState::Warning;
68+
//modelValidationError = QStringLiteral("Missing or incorrect inputs");
69+
_result.reset();
70+
}
71+
72+
Q_EMIT dataUpdated(outPortIndex);
73+
}
74+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "MathOperationDataModel.hpp"
2+
3+
#include "DecimalData.hpp"
4+
5+
unsigned int MathOperationDataModel::nPorts(PortType portType) const
6+
{
7+
unsigned int result;
8+
9+
if (portType == PortType::In)
10+
result = 2;
11+
else
12+
result = 1;
13+
14+
return result;
15+
}
16+
17+
NodeDataType MathOperationDataModel::dataType(PortType, PortIndex) const
18+
{
19+
return DecimalData().type();
20+
}
21+
22+
std::shared_ptr<NodeData> MathOperationDataModel::outData(PortIndex)
23+
{
24+
return std::static_pointer_cast<NodeData>(_result);
25+
}
26+
27+
void MathOperationDataModel::setInData(std::shared_ptr<NodeData> data, PortIndex portIndex)
28+
{
29+
auto numberData = std::dynamic_pointer_cast<DecimalData>(data);
30+
31+
if (!data) {
32+
Q_EMIT dataInvalidated(0);
33+
}
34+
35+
if (portIndex == 0) {
36+
_number1 = numberData;
37+
} else {
38+
_number2 = numberData;
39+
}
40+
41+
compute();
42+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#pragma once
2+
3+
#include <QtNodes/NodeDelegateModel>
4+
5+
#include <QtCore/QJsonObject>
6+
#include <QtCore/QObject>
7+
#include <QtWidgets/QLabel>
8+
9+
#include <iostream>
10+
11+
class DecimalData;
12+
13+
using QtNodes::NodeData;
14+
using QtNodes::NodeDataType;
15+
using QtNodes::NodeDelegateModel;
16+
using QtNodes::PortIndex;
17+
using QtNodes::PortType;
18+
19+
/// The model dictates the number of inputs and outputs for the Node.
20+
/// In this example it has no logic.
21+
class MathOperationDataModel : public NodeDelegateModel
22+
{
23+
Q_OBJECT
24+
25+
public:
26+
~MathOperationDataModel() = default;
27+
28+
public:
29+
unsigned int nPorts(PortType portType) const override;
30+
31+
NodeDataType dataType(PortType portType, PortIndex portIndex) const override;
32+
33+
std::shared_ptr<NodeData> outData(PortIndex port) override;
34+
35+
void setInData(std::shared_ptr<NodeData> data, PortIndex portIndex) override;
36+
37+
QWidget *embeddedWidget() override { return nullptr; }
38+
39+
protected:
40+
virtual void compute() = 0;
41+
42+
protected:
43+
std::weak_ptr<DecimalData> _number1;
44+
std::weak_ptr<DecimalData> _number2;
45+
46+
std::shared_ptr<DecimalData> _result;
47+
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include <QtNodes/NodeDelegateModel>
4+
5+
#include <QtCore/QObject>
6+
#include <QtWidgets/QLabel>
7+
8+
#include "MathOperationDataModel.hpp"
9+
10+
#include "DecimalData.hpp"
11+
12+
/// The model dictates the number of inputs and outputs for the Node.
13+
/// In this example it has no logic.
14+
class MultiplicationModel : public MathOperationDataModel
15+
{
16+
public:
17+
virtual ~MultiplicationModel() {}
18+
19+
public:
20+
QString caption() const override { return QStringLiteral("Multiplication"); }
21+
22+
QString name() const override { return QStringLiteral("Multiplication"); }
23+
24+
private:
25+
void compute() override
26+
{
27+
PortIndex const outPortIndex = 0;
28+
29+
auto n1 = _number1.lock();
30+
auto n2 = _number2.lock();
31+
32+
if (n1 && n2) {
33+
//modelValidationState = NodeValidationState::Valid;
34+
//modelValidationError = QString();
35+
_result = std::make_shared<DecimalData>(n1->number() * n2->number());
36+
} else {
37+
//modelValidationState = NodeValidationState::Warning;
38+
//modelValidationError = QStringLiteral("Missing or incorrect inputs");
39+
_result.reset();
40+
}
41+
42+
Q_EMIT dataUpdated(outPortIndex);
43+
}
44+
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "MyNodeEditor.hpp"
2+
3+
#include "AdditionModel.hpp"
4+
#include "DivisionModel.hpp"
5+
#include "MultiplicationModel.hpp"
6+
#include "NumberDisplayDataModel.hpp"
7+
#include "NumberSourceDataModel.hpp"
8+
#include "StringDataModel.hpp"
9+
#include "SubtractionModel.hpp"
10+
11+
std::shared_ptr<QtNodes::NodeDelegateModelRegistry> MyNodeEditor::registerDataModels() const
12+
{
13+
auto ret = std::make_shared<QtNodes::NodeDelegateModelRegistry>();
14+
ret->registerModel<NumberSourceDataModel>("Sources");
15+
16+
ret->registerModel<NumberDisplayDataModel>("Displays");
17+
18+
ret->registerModel<AdditionModel>("Operators");
19+
20+
ret->registerModel<SubtractionModel>("Operators");
21+
22+
ret->registerModel<MultiplicationModel>("Operators");
23+
24+
ret->registerModel<DivisionModel>("Operators");
25+
26+
ret->registerModel<StringDataModel>("Sources");
27+
28+
return ret;
29+
}

0 commit comments

Comments
 (0)