Skip to content

Commit

Permalink
Allow setting context properties
Browse files Browse the repository at this point in the history
  • Loading branch information
barche committed Mar 19, 2016
1 parent 0648b18 commit d5883dd
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 16 deletions.
58 changes: 44 additions & 14 deletions deps/src/qml_wrapper/wrap_qml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtQml>

#include "wrap_qml.hpp"
Expand Down Expand Up @@ -48,12 +49,6 @@ namespace detail
return QVariant();
}

// Helper to convert from Julia to a QVariant. Tries a few common types
QVariant convert_to_qt(jl_value_t* v)
{
return try_convert_to_qt<double, int64_t, QString>(v);
}

// Generic conversion from QVariant to jl_value_t*
template<typename CppT>
jl_value_t* convert_to_julia(const QVariant& v)
Expand Down Expand Up @@ -92,11 +87,34 @@ namespace detail
return nullptr;
}

jl_value_t* convert_to_julia(const QVariant& v)
} // namespace detail
} // namespace qml_wrapper

namespace cpp_wrapper
{

template<>
struct ConvertToCpp<QVariant, false, false, false>
{
return try_convert_to_julia<double, int64_t, QString>(v);
}
}
QVariant operator()(jl_value_t* julia_value) const
{
return qml_wrapper::detail::try_convert_to_qt<double, int64_t, QString>(julia_value);
}
};

template<>
struct ConvertToJulia<QVariant, false, false, false>
{
jl_value_t* operator()(const QVariant& v) const
{
return qml_wrapper::detail::try_convert_to_julia<double, int64_t, QString>(v);
}
};

} // namespace cpp_wrapper

namespace qml_wrapper
{

// Create an application, taking care of argc and argv
QApplication* application()
Expand Down Expand Up @@ -132,7 +150,7 @@ QVariant JuliaContext::call(const QString& fname, const QVariantList& args)
// Process arguments
for(int i = 0; i != nb_args; ++i)
{
julia_args[i] = detail::convert_to_julia(args.at(i));
julia_args[i] = cpp_wrapper::convert_to_julia<QVariant>(args.at(i));
if(julia_args[i] == nullptr)
{
qWarning() << "Julia argument type for function " << fname << " is unsupported:" << args[0].typeName();
Expand All @@ -152,7 +170,7 @@ QVariant JuliaContext::call(const QString& fname, const QVariantList& args)
}
else
{
result_var = detail::convert_to_qt(result);
result_var = cpp_wrapper::convert_to_cpp<QVariant>(result);
if(result_var.isNull())
{
qWarning() << "Julia method " << fname << " returns unsupported " << QString(cpp_wrapper::julia_type_name((jl_datatype_t*)jl_typeof(result)).c_str());
Expand Down Expand Up @@ -185,9 +203,21 @@ JULIA_CPP_MODULE_BEGIN(registry)
qml_module.method("application", qml_wrapper::application);
qml_module.method("exec", QApplication::exec);

qml_module.add_type<QQmlContext>("QQmlContext");
qml_module.method("set_context_property", [](QQmlContext* ctx, const std::string& name, jl_value_t* v)
{
if(ctx == nullptr)
{
qWarning() << "Can't set property " << name.c_str() << " on null context";
return;
}
ctx->setContextProperty(QString(name.c_str()), convert_to_cpp<QVariant>(v));
});

qml_module.add_type<QQmlApplicationEngine>("QQmlApplicationEngine")
.constructor<QString>(); // Construct with path to QML
.constructor<QString>() // Construct with path to QML
.method("root_context", &QQmlApplicationEngine::rootContext);

// Exports:
qml_module.export_symbols("QString", "QApplication", "QQmlApplicationEngine");
qml_module.export_symbols("QString", "QApplication", "QQmlApplicationEngine", "QQmlContext", "set_context_property", "root_context");
JULIA_CPP_MODULE_END
2 changes: 1 addition & 1 deletion test/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ ApplicationWindow {

Text {
Layout.alignment: Qt.AlignCenter
text: julia.call("string", [julia.call("counter_value"), ", ", upperOut.text])
text: julia.call("string", [oldcounter, ", ", upperOut.text])
}
}
}
6 changes: 5 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ counter = 0

function increment_counter()
global counter
global root_ctx
set_context_property(root_ctx, "oldcounter", counter)
counter += 1
end

Expand All @@ -19,7 +21,9 @@ end
qml_file = QString(joinpath(Pkg.dir("QML"), "test", "main.qml"))

app = QML.application()
e = QQmlApplicationEngine(qml_file)
qml_engine = QQmlApplicationEngine(qml_file)
root_ctx = root_context(qml_engine)
set_context_property(root_ctx, "oldcounter", counter) # avoids undefined reference at startup
QML.exec()

println("Button was pressed $counter times")

0 comments on commit d5883dd

Please sign in to comment.