Files
2026-07-26 05:59:32 +00:00

197 lines
127 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html><html lang=en dir=ltr class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-core/build-modules/build-a-logos-cpp-ui-module" data-has-hydrated=false><head><meta charset=UTF-8><meta name=generator content="Docusaurus v3.10.2"><title data-rh=true>Build a Logos C++ UI module | Logos documentation</title><meta data-rh=true name=viewport content="width=device-width, initial-scale=1.0"/><meta data-rh=true name=twitter:card content=summary_large_image /><meta data-rh=true property=og:image content=https://docs.logos.co/img/social-card.jpg /><meta data-rh=true name=twitter:image content=https://docs.logos.co/img/social-card.jpg /><meta data-rh=true property=og:url content=https://docs.logos.co/core/build-modules/build-a-logos-cpp-ui-module /><meta data-rh=true property=og:locale content=en /><meta data-rh=true name=docusaurus_locale content=en /><meta data-rh=true name=docsearch:language content=en /><meta data-rh=true name=docusaurus_version content=current /><meta data-rh=true name=docusaurus_tag content=docs-default-current /><meta data-rh=true name=docsearch:version content=current /><meta data-rh=true name=docsearch:docusaurus_tag content=docs-default-current /><meta data-rh=true property=og:title content="Build a Logos C++ UI module | Logos documentation"/><meta data-rh=true name=description content="Get started building a ui\_qml module with a C++ backend that runs in a separate process."/><meta data-rh=true property=og:description content="Get started building a ui\_qml module with a C++ backend that runs in a separate process."/><link data-rh=true rel=icon href=/img/favicon.png /><link data-rh=true rel=canonical href=https://docs.logos.co/core/build-modules/build-a-logos-cpp-ui-module /><link data-rh=true rel=alternate href=https://docs.logos.co/core/build-modules/build-a-logos-cpp-ui-module hreflang=en /><link data-rh=true rel=alternate href=https://docs.logos.co/core/build-modules/build-a-logos-cpp-ui-module hreflang=x-default /><script data-rh=true type=application/ld+json>{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","item":"https://docs.logos.co/core/build-modules/build-a-logos-cpp-ui-module","name":"Build a Logos C++ UI module","position":1}]}</script><link rel=icon href=/img/favicon.png media="(prefers-color-scheme: light)"><link rel=icon href=/img/favicon-dark.png media="(prefers-color-scheme: dark)"><link rel=stylesheet href=/assets/css/styles.e45c7411.css /><script src=/assets/js/runtime~main.ea6c7eaa.js defer></script><script src=/assets/js/main.78385118.js defer></script></head><body><svg style="display: none;"><defs>
<symbol id=theme-svg-external-link viewBox="0 0 24 24"><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol>
</defs></svg>
<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme-597")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light")),document.documentElement.setAttribute("data-theme-choice",t||"system")}(),function(){try{for(var[t,e]of new URLSearchParams(window.location.search).entries())if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id=__docusaurus><link rel=preload as=image href=/img/logo-light.png /><link rel=preload as=image href=/img/logo-dark.png /><div role=region aria-label="Skip to main content"><a class=skipToContent_fXgn href=#__docusaurus_skipToContent_fallback>Skip to main content</a></div><nav aria-label=Main class="theme-layout-navbar navbar navbar--fixed-top"><div class=navbar__inner><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded=false class="navbar__toggle clean-btn" type=button><svg width=30 height=30 viewBox="0 0 30 30" aria-hidden=true><path stroke=currentColor stroke-linecap=round stroke-miterlimit=10 stroke-width=2 d="M4 7h22M4 15h22M4 23h22"/></svg></button><a class=navbar__brand href=/><div class=navbar__logo><img src=/img/logo-light.png alt=Logos class="themedComponent_mlkZ themedComponent--light_NVdE"/><img src=/img/logo-dark.png alt=Logos class="themedComponent_mlkZ themedComponent--dark_xIcU"/></div></a><a class="navbar__item navbar__link" href=/get-started/what-is-logos>Get started</a><div class="navbar__item dropdown dropdown--hoverable"><a href=# aria-haspopup=true aria-expanded=false role=button class=navbar__link>Your path</a><ul class=dropdown__menu><li><a class=dropdown__link href=/run-an-app>Run an app</a><li><a class=dropdown__link href=/run-a-node/get-started/run-logos-node-blockchain-storage-delivery>Run a node</a><li><a class=dropdown__link href=/build-an-app>Build an app</a><li><a class=dropdown__link href=/contribute/welcome>Contribute</a></ul></div><div class="navbar__item dropdown dropdown--hoverable"><a href=# aria-haspopup=true aria-expanded=false role=button class=navbar__link>Explore</a><ul class=dropdown__menu><li><a class=dropdown__link href=/basecamp/get-started/install-logos-basecamp>Basecamp</a><li><a class=dropdown__link href=/blockchain/get-started/introduction-to-the-logos-blockchain>Blockchain</a><li><a class=dropdown__link href=/lez/get-started/introduction-to-the-logos-execution-zone>LEZ</a><li><a aria-current=page class="dropdown__link dropdown__link--active" href=/core/build-modules/start-a-logos-module-from-the-cli>Core</a><li><a class=dropdown__link href=/messaging/get-started/introduction-to-logos-messaging>Messaging</a><li><a class=dropdown__link href=/storage/get-started/run-logos-storage-node>Storage</a><li><a class=dropdown__link href=/mixnet/get-started/discover-nodes-and-send-messages-via-the-anoncomms-mixnet-demo-app>Mixnet</a><li><a class=dropdown__link href=/peer-discovery/welcome>Peer discovery</a></ul></div></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href=https://github.com/logos-co/logos-docs target=_blank rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type=button disabled title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_g3eP lightToggleIcon_pyhR"><path fill=currentColor d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_g3eP darkToggleIcon_wfgR"><path fill=currentColor d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/></svg><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_g3eP systemToggleIcon_QzmC"><path fill=currentColor d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"/></svg></button></div><div class=navbarSearchContainer_Bca1></div></div></div><div role=presentation class=navbar-sidebar__backdrop></div></nav><div id=__docusaurus_skipToContent_fallback class="theme-layout-main main-wrapper mainWrapper_z2l0"><div class=docsWrapper_hBAB><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type=button></button><div class=docRoot_UBD9><aside class="theme-doc-sidebar-container docSidebarContainer_YfHR"><div class=sidebarViewport_aRkj><div class=sidebar_njMd><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" role=button aria-expanded=true href=/core/build-modules/start-a-logos-module-from-the-cli><span class=categoryLinkLabel_W154>Build modules</span></a></div><ul class=menu__list><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/core/build-modules/start-a-logos-module-from-the-cli><span class=linkLabel_WmDU>Start a Logos module from the CLI</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/core/build-modules/build-and-run-a-logos-core-module><span class=linkLabel_WmDU>Build and run a Logos core module</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/core/build-modules/wrap-a-c-library-as-a-logos-core-module><span class=linkLabel_WmDU>Wrap a C library as a Logos module</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current=page tabindex=0 href=/core/build-modules/build-a-logos-cpp-ui-module><span class=linkLabel_WmDU>Build a Logos C++ UI module</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/core/build-modules/install-and-load-a-module-in-logos-basecamp><span class=linkLabel_WmDU>Install and load a module in Logos Basecamp</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/core/build-modules/build-logos-core-module-that-uses-service-discovery-api><span class=linkLabel_WmDU>Build a Logos Core module that uses the Service Discovery API</span></a></ul><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/core/reference/lgx-package-format-and-bundling-reference><span class=categoryLinkLabel_W154>Reference</span></a></div></ul></nav></div></div></aside><main class=docMainContainer_TBSr><div class="container padding-top--md padding-bottom--lg"><div class=row><div class="col docItemCol_VOVn"><div class=docItemContainer_Djhp><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label=Breadcrumbs><ul class=breadcrumbs><li class=breadcrumbs__item><a aria-label="Home page" class=breadcrumbs__link href=/><svg viewBox="0 0 24 24" class=breadcrumbHomeIcon_YNFT><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill=currentColor /></svg></a><li class=breadcrumbs__item><span class=breadcrumbs__link>Build modules</span><li class="breadcrumbs__item breadcrumbs__item--active"><span class=breadcrumbs__link>Build a Logos C++ UI module</span></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type=button class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Build a Logos C++ UI module</h1></header>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id=get-started-building-a-ui_qml-module-with-a-c-backend-that-runs-in-a-separate-process>Get started building a ui_qml module with a C++ backend that runs in a separate process.<a href=#get-started-building-a-ui_qml-module-with-a-c-backend-that-runs-in-a-separate-process class=hash-link aria-label="Direct link to Get started building a ui_qml module with a C++ backend that runs in a separate process." title="Direct link to Get started building a ui_qml module with a C++ backend that runs in a separate process." translate=no></a></h4>
<p>This guide covers building a <a href=https://docs.logos.co/get-started/glossary#module target=_blank rel="noopener noreferrer" class="">module</a> that pairs a QML user interface with a C++ backend plugin. The backend runs in a separate <code>ui-host</code> process while the QML view loads inside the host app (<code>logos-basecamp</code> or <code>logos-standalone-app</code>), so a backend crash cannot bring down the host. This guide is intended for developers who have completed <a class="" href=/core/build-modules/wrap-a-c-library-as-a-logos-core-module>Part 1</a> and want typed, process-isolated inter-module calls from their UI layer.</p>
<p><strong>Before you start</strong>, make sure you have the following:</p>
<ul>
<li class="">Completed <a class="" href=/core/build-modules/wrap-a-c-library-as-a-logos-core-module>Part 1</a> — a working <code>calc_module</code> with the shared library built in <code>logos-calc-module/lib/</code>.</li>
<li class="">Nix with flakes enabled.</li>
<li class="">Basic familiarity with <a href=https://doc.qt.io/qt-6/qmlapplications.html target=_blank rel="noopener noreferrer" class="">QML</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=what-to-expect>What to expect<a href=#what-to-expect class=hash-link aria-label="Direct link to What to expect" title="Direct link to What to expect" translate=no></a></h2>
<ul>
<li class="">You can scaffold, configure, and build a <code>calc_ui_cpp</code> module with a process-isolated C++ backend.</li>
<li class="">You can call <code>calc_module</code> methods from QML using a typed replica and <code>logos.watch()</code>.</li>
<li class="">You will be able to build, run, and live-reload the module using <code>nix run</code>.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-1-scaffold-the-project>Step 1: Scaffold the project<a href=#step-1-scaffold-the-project class=hash-link aria-label="Direct link to Step 1: Scaffold the project" title="Direct link to Step 1: Scaffold the project" translate=no></a></h2>
<p>Create a new directory and initialise it from the C++ backend UI template.</p>
<ol>
<li class="">
<p>Create and enter the project directory:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">mkdir logos-calc-ui-cpp && cd logos-calc-ui-cpp</span><br/></div></code></pre></div></div>
</li>
<li class="">
<p>Initialise from the template:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">nix flake init -t github:logos-co/logos-module-builder/0.2.0#ui-qml-backend</span><br/></div></code></pre></div></div>
</li>
<li class="">
<p>Initialise a Git repository and stage all generated files:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">git init && git add -A</span><br/></div></code></pre></div></div>
</li>
<li class="">
<p>Remove the template's example sources. The scaffolded template includes <code>ui_example</code> files with mismatched class names and IIDs; leaving them causes build errors or plugin-load failures at runtime:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">rm -f src/ui_example.rep src/ui_example_interface.h src/ui_example_plugin.h src/ui_example_plugin.cpp</span><br/></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-2-configure-the-module-metadata>Step 2: Configure the module metadata<a href=#step-2-configure-the-module-metadata class=hash-link aria-label="Direct link to Step 2: Configure the module metadata" title="Direct link to Step 2: Configure the module metadata" translate=no></a></h2>
<p>Replace the template <code>metadata.json</code> with your plugin's details.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class=admonitionHeading_Gvgb><span class=admonitionIcon_Rf37><svg viewBox="0 0 14 16"><path fill-rule=evenodd d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg></span>info</div><div class=admonitionContent_BuS1><p>The <code>calc_module.url</code> input attribute name in <code>flake.nix</code> must match the dependency name declared here in <code>"dependencies"</code>.</div></div>
<ol>
<li class="">
<p>Replace <code>metadata.json</code> with the following:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-json codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"name"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"calc_ui_cpp"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"version"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"1.0.0"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"type"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"ui_qml"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"category"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"tools"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"description"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"Calculator C++ UI — QML view with process-isolated backend for calc_module"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"main"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"calc_ui_cpp_plugin"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"view"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"qml/Main.qml"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"icon"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"icons/calc.png"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"dependencies"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>[</span><span class="token string" style=color:#e3116c>"calc_module"</span><span class="token punctuation" style=color:#393A34>]</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"nix"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"packages"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token property" style=color:#36acaa>"build"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>[</span><span class="token punctuation" style=color:#393A34>]</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token property" style=color:#36acaa>"runtime"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>[</span><span class="token punctuation" style=color:#393A34>]</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"external_libraries"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>[</span><span class="token punctuation" style=color:#393A34>]</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"cmake"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"find_packages"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>[</span><span class="token punctuation" style=color:#393A34>]</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"extra_sources"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>[</span><span class="token punctuation" style=color:#393A34>]</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"extra_include_dirs"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>[</span><span class="token punctuation" style=color:#393A34>]</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token property" style=color:#36acaa>"extra_link_libraries"</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>[</span><span class="token punctuation" style=color:#393A34>]</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>}</span><br/></div></code></pre></div></div>
<p>Key fields:</p>
<ul>
<li class=""><code>"type": "ui_qml"</code> — tells the builder this is a QML view module.</li>
<li class=""><code>"main": "calc_ui_cpp_plugin"</code> — the backend Qt plugin library name (without extension).</li>
<li class=""><code>"view": "qml/Main.qml"</code> — the QML entry point.</li>
<li class=""><code>"dependencies": ["calc_module"]</code><a href=https://docs.logos.co/get-started/glossary#core-module target=_blank rel="noopener noreferrer" class="">core modules</a> the backend calls.</li>
</ul>
</li>
<li class="">
<p>Create the icons directory and add a placeholder icon (displayed in the <code>logos-basecamp</code> sidebar when the module is loaded):</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">mkdir -p icons</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Copy any PNG here - or generate a 64x64 placeholder:</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">echo "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAmElEQVR4nO3QMREAIBDAsFeEN3ziCWRkoEP2XmedfX82OkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAO0BN/SiO/PatoIAAAAASUVORK5CYII=" | base64 -d > icons/calc.png</span><br/></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-3-define-the-remote-interface>Step 3: Define the remote interface<a href=#step-3-define-the-remote-interface class=hash-link aria-label="Direct link to Step 3: Define the remote interface" title="Direct link to Step 3: Define the remote interface" translate=no></a></h2>
<p>The <code>.rep</code> file is the single source of truth for the interface between the QML view and the C++ backend. <code>repc</code> compiles it at build time into typed source and replica headers.</p>
<ol>
<li class="">
<p>Create <code>src/calc_ui_cpp.rep</code>:</p>
<div class="language-rep codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-rep codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">class CalcUiCpp</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">{</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> SLOT(int add(int a, int b))</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> SLOT(int multiply(int a, int b))</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> SLOT(int factorial(int n))</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> SLOT(int fibonacci(int n))</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> SLOT(QString libVersion())</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">}</span><br/></div></code></pre></div></div>
<p><code>repc</code> generates two headers from this file:</p>
<ul>
<li class=""><code>rep_calc_ui_cpp_source.h</code><code>CalcUiCppSimpleSource</code> with virtual slots the backend overrides.</li>
<li class=""><code>rep_calc_ui_cpp_replica.h</code><code>CalcUiCppReplica</code> with typed methods the QML view calls.</li>
</ul>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-4-write-the-interface-header>Step 4: Write the interface header<a href=#step-4-write-the-interface-header class=hash-link aria-label="Direct link to Step 4: Write the interface header" title="Direct link to Step 4: Write the interface header" translate=no></a></h2>
<p>Create <code>src/calc_ui_cpp_interface.h</code>:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>ifndef</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property expression" style=color:#36acaa>CALC_UI_CPP_INTERFACE_H</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>define</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property macro-name" style=color:#36acaa>CALC_UI_CPP_INTERFACE_H</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>&lt;QObject></span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>&lt;QString></span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>"interface.h"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>class</span><span class="token plain"> </span><span class="token class-name">CalcUiCppInterface</span><span class="token plain"> </span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token base-clause keyword" style=color:#00009f>public</span><span class="token base-clause"> </span><span class="token base-clause class-name">PluginInterface</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>public</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>virtual</span><span class="token plain"> </span><span class="token operator" style=color:#393A34>~</span><span class="token function" style=color:#d73a49>CalcUiCppInterface</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token operator" style=color:#393A34>=</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>default</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>}</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>define</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property macro-name" style=color:#36acaa>CalcUiCppInterface_iid</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>"org.logos.CalcUiCppInterface"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token function" style=color:#d73a49>Q_DECLARE_INTERFACE</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">CalcUiCppInterface</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> CalcUiCppInterface_iid</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>endif</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property comment" style=color:#999988;font-style:italic>// CALC_UI_CPP_INTERFACE_H</span><br/></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-5-configure-the-cmake-build>Step 5: Configure the CMake build<a href=#step-5-configure-the-cmake-build class=hash-link aria-label="Direct link to Step 5: Configure the CMake build" title="Direct link to Step 5: Configure the CMake build" translate=no></a></h2>
<p>Create <code>CMakeLists.txt</code>:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">cmake_minimum_required(VERSION 3.14)</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">project(CalcUiCppPlugin LANGUAGES CXX)</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">if(DEFINED ENV{LOGOS_MODULE_BUILDER_ROOT})</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> include($ENV{LOGOS_MODULE_BUILDER_ROOT}/cmake/LogosModule.cmake)</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">else()</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> message(FATAL_ERROR "LogosModule.cmake not found. Set LOGOS_MODULE_BUILDER_ROOT.")</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">endif()</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">logos_module(</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> NAME calc_ui_cpp</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> REP_FILE src/calc_ui_cpp.rep</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> SOURCES</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> src/calc_ui_cpp_interface.h</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> src/calc_ui_cpp_plugin.h</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> src/calc_ui_cpp_plugin.cpp</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">)</span><br/></div></code></pre></div></div>
<p><code>REP_FILE</code> tells <code>logos_module()</code> to run <code>repc</code> to generate source/replica headers, generate <code>CalcUiCppViewPluginBase</code>, and build a separate <code>calc_ui_cpp_replica_factory</code> shared library.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-6-write-the-c-backend-plugin>Step 6: Write the C++ backend plugin<a href=#step-6-write-the-c-backend-plugin class=hash-link aria-label="Direct link to Step 6: Write the C++ backend plugin" title="Direct link to Step 6: Write the C++ backend plugin" translate=no></a></h2>
<p>The backend plugin inherits three base classes:</p>
<ul>
<li class=""><code>CalcUiCppSimpleSource</code> — generated from <code>.rep</code>, provides the typed source for Qt Remote Objects.</li>
<li class=""><code>CalcUiCppInterface</code> — standard Logos plugin interface (<code>name()</code>, <code>version()</code>).</li>
<li class=""><code>CalcUiCppViewPluginBase</code> — generated, provides <code>setBackend()</code> and <code>enableRemoting()</code>.</li>
</ul>
<ol>
<li class="">
<p>Create <code>src/calc_ui_cpp_plugin.h</code>:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>ifndef</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property expression" style=color:#36acaa>CALC_UI_CPP_PLUGIN_H</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>define</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property macro-name" style=color:#36acaa>CALC_UI_CPP_PLUGIN_H</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>&lt;QString></span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>&lt;QVariantList></span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>"calc_ui_cpp_interface.h"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>"LogosViewPluginBase.h"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>"rep_calc_ui_cpp_source.h"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>class</span><span class="token plain"> </span><span class="token class-name">LogosAPI</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>class</span><span class="token plain"> </span><span class="token class-name">LogosModules</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>class</span><span class="token plain"> </span><span class="token class-name">CalcUiCppPlugin</span><span class="token plain"> </span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token base-clause keyword" style=color:#00009f>public</span><span class="token base-clause"> </span><span class="token base-clause class-name">CalcUiCppSimpleSource</span><span class="token base-clause punctuation" style=color:#393A34>,</span><span class="token base-clause"></span><br/></div><div class=token-line style=color:#393A34><span class="token base-clause"> </span><span class="token base-clause keyword" style=color:#00009f>public</span><span class="token base-clause"> </span><span class="token base-clause class-name">CalcUiCppInterface</span><span class="token base-clause punctuation" style=color:#393A34>,</span><span class="token base-clause"></span><br/></div><div class=token-line style=color:#393A34><span class="token base-clause"> </span><span class="token base-clause keyword" style=color:#00009f>public</span><span class="token base-clause"> </span><span class="token base-clause class-name">CalcUiCppViewPluginBase</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Q_OBJECT</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token function" style=color:#d73a49>Q_PLUGIN_METADATA</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">IID CalcUiCppInterface_iid FILE </span><span class="token string" style=color:#e3116c>"metadata.json"</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token function" style=color:#d73a49>Q_INTERFACES</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">CalcUiCppInterface</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>public</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>explicit</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>CalcUiCppPlugin</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">QObject</span><span class="token operator" style=color:#393A34>*</span><span class="token plain"> parent </span><span class="token operator" style=color:#393A34>=</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>nullptr</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token operator" style=color:#393A34>~</span><span class="token function" style=color:#d73a49>CalcUiCppPlugin</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>override</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> QString </span><span class="token function" style=color:#d73a49>name</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>const</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>override</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>return</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"calc_ui_cpp"</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> QString </span><span class="token function" style=color:#d73a49>version</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>const</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>override</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>return</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"1.0.0"</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Q_INVOKABLE </span><span class="token keyword" style=color:#00009f>void</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>initLogos</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">LogosAPI</span><span class="token operator" style=color:#393A34>*</span><span class="token plain"> api</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token comment" style=color:#999988;font-style:italic>// Slots from calc_ui_cpp.rep — return values directly. The QML replica</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token comment" style=color:#999988;font-style:italic>// receives QRemoteObjectPendingReply; use logos.watch() in QML to get the value.</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>add</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> a</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> b</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>override</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>multiply</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> a</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> b</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>override</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>factorial</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> n</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>override</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>fibonacci</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> n</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>override</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> QString </span><span class="token function" style=color:#d73a49>libVersion</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>override</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">signals</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>void</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>eventResponse</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>const</span><span class="token plain"> QString</span><span class="token operator" style=color:#393A34>&</span><span class="token plain"> eventName</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>const</span><span class="token plain"> QVariantList</span><span class="token operator" style=color:#393A34>&</span><span class="token plain"> args</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>private</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> LogosAPI</span><span class="token operator" style=color:#393A34>*</span><span class="token plain"> m_logosAPI </span><span class="token operator" style=color:#393A34>=</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>nullptr</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> LogosModules</span><span class="token operator" style=color:#393A34>*</span><span class="token plain"> m_logos </span><span class="token operator" style=color:#393A34>=</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>nullptr</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>}</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>endif</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property comment" style=color:#999988;font-style:italic>// CALC_UI_CPP_PLUGIN_H</span><br/></div></code></pre></div></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class=admonitionHeading_Gvgb><span class=admonitionIcon_Rf37><svg viewBox="0 0 14 16"><path fill-rule=evenodd d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg></span>info</div><div class=admonitionContent_BuS1><p>If the interface filename or IID symbol here doesn't match the names in <code>src/calc_ui_cpp_interface.h</code>, you will get build errors or plugin-load failures at runtime.</div></div>
</li>
<li class="">
<p>Create <code>src/calc_ui_cpp_plugin.cpp</code>:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>"calc_ui_cpp_plugin.h"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>"logos_api.h"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token macro property directive-hash" style=color:#36acaa>#</span><span class="token macro property directive keyword" style=color:#00009f>include</span><span class="token macro property" style=color:#36acaa> </span><span class="token macro property string" style=color:#e3116c>"logos_sdk.h"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token class-name">CalcUiCppPlugin</span><span class="token double-colon punctuation" style=color:#393A34>::</span><span class="token function" style=color:#d73a49>CalcUiCppPlugin</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">QObject</span><span class="token operator" style=color:#393A34>*</span><span class="token plain"> parent</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>CalcUiCppSimpleSource</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">parent</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token class-name">CalcUiCppPlugin</span><span class="token double-colon punctuation" style=color:#393A34>::</span><span class="token operator" style=color:#393A34>~</span><span class="token function" style=color:#d73a49>CalcUiCppPlugin</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>delete</span><span class="token plain"> m_logos</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>void</span><span class="token plain"> </span><span class="token class-name">CalcUiCppPlugin</span><span class="token double-colon punctuation" style=color:#393A34>::</span><span class="token function" style=color:#d73a49>initLogos</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">LogosAPI</span><span class="token operator" style=color:#393A34>*</span><span class="token plain"> api</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>if</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">m_logos</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>return</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> m_logosAPI </span><span class="token operator" style=color:#393A34>=</span><span class="token plain"> api</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> m_logos </span><span class="token operator" style=color:#393A34>=</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>new</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>LogosModules</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">api</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token comment" style=color:#999988;font-style:italic>// Register this object as the Remote Objects source so the QML replica</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token comment" style=color:#999988;font-style:italic>// can see its properties and call its slots.</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token function" style=color:#d73a49>setBackend</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>this</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> </span><span class="token class-name">CalcUiCppPlugin</span><span class="token double-colon punctuation" style=color:#393A34>::</span><span class="token function" style=color:#d73a49>add</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> a</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> b</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>return</span><span class="token plain"> m_logos</span><span class="token operator" style=color:#393A34>-></span><span class="token plain">calc_module</span><span class="token punctuation" style=color:#393A34>.</span><span class="token function" style=color:#d73a49>add</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">a</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> b</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> </span><span class="token class-name">CalcUiCppPlugin</span><span class="token double-colon punctuation" style=color:#393A34>::</span><span class="token function" style=color:#d73a49>multiply</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> a</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> b</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>return</span><span class="token plain"> m_logos</span><span class="token operator" style=color:#393A34>-></span><span class="token plain">calc_module</span><span class="token punctuation" style=color:#393A34>.</span><span class="token function" style=color:#d73a49>multiply</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">a</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> b</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> </span><span class="token class-name">CalcUiCppPlugin</span><span class="token double-colon punctuation" style=color:#393A34>::</span><span class="token function" style=color:#d73a49>factorial</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> n</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>return</span><span class="token plain"> m_logos</span><span class="token operator" style=color:#393A34>-></span><span class="token plain">calc_module</span><span class="token punctuation" style=color:#393A34>.</span><span class="token function" style=color:#d73a49>factorial</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">n</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> </span><span class="token class-name">CalcUiCppPlugin</span><span class="token double-colon punctuation" style=color:#393A34>::</span><span class="token function" style=color:#d73a49>fibonacci</span><span class="token punctuation" style=color:#393A34>(</span><span class="token keyword" style=color:#00009f>int</span><span class="token plain"> n</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>return</span><span class="token plain"> m_logos</span><span class="token operator" style=color:#393A34>-></span><span class="token plain">calc_module</span><span class="token punctuation" style=color:#393A34>.</span><span class="token function" style=color:#d73a49>fibonacci</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">n</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">QString </span><span class="token class-name">CalcUiCppPlugin</span><span class="token double-colon punctuation" style=color:#393A34>::</span><span class="token function" style=color:#d73a49>libVersion</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>return</span><span class="token plain"> m_logos</span><span class="token operator" style=color:#393A34>-></span><span class="token plain">calc_module</span><span class="token punctuation" style=color:#393A34>.</span><span class="token function" style=color:#d73a49>libVersion</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>}</span><br/></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-7-write-the-qml-view>Step 7: Write the QML view<a href=#step-7-write-the-qml-view class=hash-link aria-label="Direct link to Step 7: Write the QML view" title="Direct link to Step 7: Write the QML view" translate=no></a></h2>
<ol>
<li class="">
<p>Create <code>src/qml/Main.qml</code>:</p>
<div class="language-qml codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-qml codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">import QtQuick</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">import QtQuick.Controls</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">import QtQuick.Layouts</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">Item {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> id: root</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> property string result: ""</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> property string errorText: ""</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> // Typed replica of the backend running in ui-host (generated from calc_ui_cpp.rep).</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> readonly property var backend: logos.module("calc_ui_cpp")</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> // The ui-host backend connects asynchronously, so the replica isn't</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> // immediately usable. Track readiness reactively: isViewModuleReady()</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> // is a Q_INVOKABLE (not a property), so we re-check it on the</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> // onViewModuleReadyChanged signal and once at startup — never via a</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> // plain property binding, which would not re-evaluate.</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> property bool ready: false</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Connections {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> target: logos</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> function onViewModuleReadyChanged(moduleName, isReady) {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> if (moduleName === "calc_ui_cpp")</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> root.ready = isReady && root.backend !== null</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Component.onCompleted: {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> root.ready = root.backend !== null && logos.isViewModuleReady("calc_ui_cpp")</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> // logos.watch() delivers the result of a replica slot call via callbacks.</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> function callCalc(method, args) {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> if (!root.ready) {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> root.errorText = "Backend not ready"</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> return</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> root.errorText = ""</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> root.result = "..."</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> logos.watch(backend[method].apply(backend, args),</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> function(value) { root.result = String(value) },</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> function(error) { root.errorText = String(error) }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> )</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> ColumnLayout {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> anchors.fill: parent</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> anchors.margins: 24</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> spacing: 16</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Text {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> text: "Logos Calculator (C++ backend)"</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> font.pixelSize: 20</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> color: "#ffffff"</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Layout.alignment: Qt.AlignHCenter</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> // Reactive backend-connection indicator.</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Text {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> text: root.ready ? "Connected" : "Connecting to backend..."</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> color: root.ready ? "#56d364" : "#f0883e"</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> font.pixelSize: 12</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Layout.alignment: Qt.AlignHCenter</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> RowLayout {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> spacing: 12</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Layout.fillWidth: true</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> TextField { id: inputA; placeholderText: "a"; Layout.preferredWidth: 80; validator: IntValidator {} }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> TextField { id: inputB; placeholderText: "b"; Layout.preferredWidth: 80; validator: IntValidator {} }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Button {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> text: "Add"; enabled: root.ready</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> onClicked: root.callCalc("add", [parseInt(inputA.text) || 0, parseInt(inputB.text) || 0])</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Button {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> text: "Multiply"; enabled: root.ready</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> onClicked: root.callCalc("multiply", [parseInt(inputA.text) || 0, parseInt(inputB.text) || 0])</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> RowLayout {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> spacing: 12</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Layout.fillWidth: true</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> TextField { id: inputN; placeholderText: "n"; Layout.preferredWidth: 80; validator: IntValidator { bottom: 0 } }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Button { text: "Factorial"; enabled: root.ready; onClicked: root.callCalc("factorial", [parseInt(inputN.text) || 0]) }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Button { text: "Fibonacci"; enabled: root.ready; onClicked: root.callCalc("fibonacci", [parseInt(inputN.text) || 0]) }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Button { text: "libcalc version"; enabled: root.ready; onClicked: root.callCalc("libVersion", []) }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Rectangle {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Layout.fillWidth: true</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> height: 56</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> color: root.errorText.length > 0 ? "#3d1a1a" : "#1a2d1a"</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> radius: 8</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Text {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> anchors.centerIn: parent</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> text: root.errorText.length > 0 ? root.errorText</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> : (root.result.length > 0 ? root.result : "Enter values and press a button")</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> color: root.errorText.length > 0 ? "#f85149" : "#56d364"</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> font.pixelSize: 15</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> Item { Layout.fillHeight: true }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">}</span><br/></div></code></pre></div></div>
<p>Key patterns:</p>
<ul>
<li class=""><code>logos.module("calc_ui_cpp")</code> — gets the typed replica, with auto-synced properties.</li>
<li class=""><code>logos.watch(backend.add(1, 2), ...)</code> — delivers a <code>SLOT</code> return value as a JS Promise.</li>
<li class="">The <code>logos</code> object is injected by the host at runtime — no <code>QtRemoteObjects</code> import is needed.</li>
</ul>
</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-75-use-the-logos-design-system-in-your-qml-optional>Step 7.5: Use the Logos Design System in your QML (Optional)<a href=#step-75-use-the-logos-design-system-in-your-qml-optional class=hash-link aria-label="Direct link to Step 7.5: Use the Logos Design System in your QML (Optional)" title="Direct link to Step 7.5: Use the Logos Design System in your QML (Optional)" translate=no></a></h3>
<p>The QML view runs inside the <a href=https://github.com/logos-co/logos-standalone-app target=_blank rel="noopener noreferrer" class=""><code>logos-standalone-app</code></a> host app, which already has <a href=https://github.com/logos-co/logos-design-system target=_blank rel="noopener noreferrer" class=""><code>logos-design-system</code></a> on its import path. Use its themed components directly to automatically give your module a polished, consistent look.</p>
<ol>
<li class="">
<p>In <code>src/qml/Main.qml</code>, add the necessary imports and replace raw <code>Button</code> and <code>TextField</code> elements with design system equivalents:</p>
<div class="language-qml codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-qml codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">import Logos.Theme</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">import Logos.Controls</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">import Logos.Icons // optional shared icon assets</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">...</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">// Instead of Button:</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">LogosButton {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> text: qsTr("Add")</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> onClicked: root.callCalc("add", [parseInt(inputA.text) || 0,</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> parseInt(inputB.text) || 0])</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">}</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">...</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">// Instead of TextField:</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">LogosTextField {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> id: inputA</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> placeholderText: qsTr("a")</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">}</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">...</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">// Use theme colors instead of hardcoded hex values:</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">Rectangle {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> color: Theme.palette.backgroundSecondary</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> radius: Theme.spacing.radiusSmall</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> LogosText { text: qsTr("Result"); color: Theme.palette.text }</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">}</span><br/></div></code></pre></div></div>
</li>
<li class="">
<p>Explore available components by running the design system storybook in the logos-design-system repo:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">git clone https://github.com/logos-co/logos-design-system.git</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">cd logos-design-system && nix run</span><br/></div></code></pre></div></div>
<p>The sidebar splits components into:</p>
<ul>
<li class=""><strong>Controls</strong> — designed per Figma, production-ready (<code>LogosButton</code>, <code>LogosBadge</code>, <code>LogosCheckbox</code>, <code>LogosComboBox</code>, <code>LogosIconButton</code>, <code>LogosPaginator</code>, <code>LogosSearchBar</code>, <code>LogosTabBar</code>, <code>LogosTable</code>, <code>LogosText</code>, <code>LogosTextField</code>, <code>LogosToolTip</code>, …).</li>
<li class=""><strong>Controls (not designed)</strong> — placeholders with stable APIs but unstyled visuals (<code>LogosDialog</code>, <code>LogosDrawer</code>, <code>LogosScrollView</code>, <code>LogosSpinner</code>, <code>LogosTextArea</code>, <code>LogosSwitch</code>, …). You can ship with them; they'll get the polished look applied later without you having to change your QML.</li>
</ul>
<p><strong>Theme tokens</strong> (use these instead of hex literals or manual font sizes):</p>
<ul>
<li class=""><code>Theme.palette.-</code><code>background</code>, <code>backgroundSecondary</code>, <code>surface</code>, <code>text</code>, <code>textSecondary</code>, <code>border</code>, <code>primary</code>, <code>success</code>, <code>warning</code>, <code>error</code>, <code>info</code>, <code>hover</code>, <code>pressed</code>, …</li>
<li class=""><code>Theme.spacing.*</code><code>tiny</code>, <code>small</code>, <code>medium</code>, <code>large</code>, <code>xlarge</code>, <code>xxlarge</code>, <code>radiusSmall</code>, <code>radiusMedium</code>, <code>radiusLarge</code></li>
<li class=""><code>Theme.typography.*</code><code>pageTitleText</code> (36), <code>titleText</code> (30), <code>panelTitleText</code> (24), <code>subtitleText</code> (16), <code>primaryText</code> (14), <code>secondaryText</code> (12); <code>weightRegular</code> / <code>weightMedium</code> / <code>weightBold</code>; <code>publicSans</code></li>
<li class=""><code>Logos.Icons.LogosIcons.*</code><code>arrowLeft</code>, <code>arrowRight</code>, <code>refresh</code>, <code>install</code>, <code>trash</code>, <code>more</code>, <code>search</code>, …</li>
</ul>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-8-configure-the-nix-flake>Step 8: Configure the Nix flake<a href=#step-8-configure-the-nix-flake class=hash-link aria-label="Direct link to Step 8: Configure the Nix flake" title="Direct link to Step 8: Configure the Nix flake" translate=no></a></h2>
<p>The template already wires everything up. Update the description and point <code>calc_module</code> at your dependency.</p>
<ol>
<li class="">
<p>Replace <code>flake.nix</code> with the following:</p>
<div class="language-nix codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-nix codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">{</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> description = "Calculator C++ UI plugin for Logos - QML view with process-isolated backend for calc_module";</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> inputs = {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> logos-module-builder.url = "github:logos-co/logos-module-builder/0.2.0";</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> # Keep this placeholder as is - it gets locked to your real path in the next step.</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> calc_module.url = "path:/path/to/your/calc_module";</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> };</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> outputs = inputs@{ logos-module-builder, calc_module, ... }:</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> logos-module-builder.lib.mkLogosQmlModule {</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> src = ./.;</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> configFile = ./metadata.json;</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> flakeInputs = inputs;</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> };</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">}</span><br/></div></code></pre></div></div>
<p>To point at a published repo instead of a local path, change the <code>calc_module.url</code> input to a <code>github:</code> URL, for example <code>calc_module.url = "github:&lt;your-org>/&lt;your-calc-module>";</code>.</p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-9-build-and-run-the-module>Step 9: Build and run the module<a href=#step-9-build-and-run-the-module class=hash-link aria-label="Direct link to Step 9: Build and run the module" title="Direct link to Step 9: Build and run the module" translate=no></a></h2>
<p>Before building, confirm the <code>calc_module</code> shared library is present from <a class="" href=/core/build-modules/wrap-a-c-library-as-a-logos-core-module>Part 1</a>.</p>
<ol>
<li class="">
<p>Confirm the shared library exists:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain"># Linux</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">ls ../logos-calc-module/lib/libcalc.so</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># macOS</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">ls ../logos-calc-module/lib/libcalc.dylib</span><br/></div></code></pre></div></div>
<p>If the file is missing, build it first:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">cd ../logos-calc-module/lib</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">gcc -shared -fPIC -o libcalc.so libcalc.c # Linux</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># gcc -shared -fPIC -o libcalc.dylib libcalc.c # macOS</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">cd ../../logos-calc-ui-cpp</span><br/></div></code></pre></div></div>
</li>
<li class="">
<p>Stage all files, then lock <code>calc_module</code> to your local Part 1 checkout. The <code>--override-input</code> flag resolves <code>../logos-calc-module</code> to an absolute path and records it in <code>flake.lock</code>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">git add -A</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">nix flake update --override-input calc_module path:../logos-calc-module</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">git add flake.lock</span><br/></div></code></pre></div></div>
</li>
<li class="">
<p>Build and run the app. After the lock is in place, no override flag is needed on subsequent commands:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">nix run</span><br/></div></code></pre></div></div>
</li>
<li class="">
<p>Confirm the view loads with all controls visible, then click <strong>Add</strong> with values in the input fields to test it out:</p>
<p><img decoding=async loading=lazy alt="Operation buttons visible" src=/assets/images/calc-cpp-buttons-78885e103cdbbb8e471c0fbc6fbfdc01.png width=1024 height=768 class=img_ev3q /></p>
<p><img decoding=async loading=lazy alt="Result of 3 + 5 shows 8" src=/assets/images/calc-cpp-result-c33b1cae801fad3be492d3ad9b1a829d.png width=1024 height=768 class=img_ev3q /></p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-10-update-view-with-live-reloading-optional>Step 10: Update view with live reloading (Optional)<a href=#step-10-update-view-with-live-reloading-optional class=hash-link aria-label="Direct link to Step 10: Update view with live reloading (Optional)" title="Direct link to Step 10: Update view with live reloading (Optional)" translate=no></a></h2>
<p>To enable live updates to the UI, set <code>DEV_QML_PATH</code> to the directory that contains your view entry's basename. This tutorial sets <code>"view": "qml/Main.qml"</code> in <code>metadata.json</code>, so the directory must contain <code>Main.qml</code> (here: <code>src/qml/</code>).</p>
<ol>
<li class="">
<p>Run with <code>DEV_QML_PATH</code> set so that QML is loaded from your source tree at runtime:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">DEV_QML_PATH=$PWD/src/qml nix run .</span><br/></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=step-11-add-ui-integration-tests-optional>Step 11: Add UI integration tests (Optional)<a href=#step-11-add-ui-integration-tests-optional class=hash-link aria-label="Direct link to Step 11: Add UI integration tests (Optional)" title="Direct link to Step 11: Add UI integration tests (Optional)" translate=no></a></h2>
<p>Add automated UI tests using the <a href=https://github.com/logos-co/logos-qt-mcp target=_blank rel="noopener noreferrer" class="">logos-qt-mcp</a> test framework.</p>
<ol>
<li class="">
<p>Create <code>tests/ui-tests.mjs</code>:</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token keyword module" style=color:#00009f>import</span><span class="token plain"> </span><span class="token imports punctuation" style=color:#393A34>{</span><span class="token imports"> resolve </span><span class="token imports punctuation" style=color:#393A34>}</span><span class="token plain"> </span><span class="token keyword module" style=color:#00009f>from</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"node:path"</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token comment" style=color:#999988;font-style:italic>// CI sets LOGOS_QT_MCP automatically; for interactive use: nix build .#test-framework -o result-mcp</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>const</span><span class="token plain"> root </span><span class="token operator" style=color:#393A34>=</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> process</span><span class="token punctuation" style=color:#393A34>.</span><span class="token property-access">env</span><span class="token punctuation" style=color:#393A34>.</span><span class="token constant" style=color:#36acaa>LOGOS_QT_MCP</span><span class="token plain"> </span><span class="token operator" style=color:#393A34>||</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>new</span><span class="token plain"> </span><span class="token class-name">URL</span><span class="token punctuation" style=color:#393A34>(</span><span class="token string" style=color:#e3116c>"../result-mcp"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token keyword module" style=color:#00009f>import</span><span class="token punctuation" style=color:#393A34>.</span><span class="token property-access">meta</span><span class="token punctuation" style=color:#393A34>.</span><span class="token property-access">url</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>.</span><span class="token property-access">pathname</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>const</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> test</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> run </span><span class="token punctuation" style=color:#393A34>}</span><span class="token plain"> </span><span class="token operator" style=color:#393A34>=</span><span class="token plain"> </span><span class="token keyword control-flow" style=color:#00009f>await</span><span class="token plain"> </span><span class="token keyword module" style=color:#00009f>import</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token function" style=color:#d73a49>resolve</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain">root</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"test-framework/framework.mjs"</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token function" style=color:#d73a49>test</span><span class="token punctuation" style=color:#393A34>(</span><span class="token string" style=color:#e3116c>"calc_ui_cpp: loads and shows title"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>async</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>(</span><span class="token parameter">app</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token arrow operator" style=color:#393A34>=></span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword control-flow" style=color:#00009f>await</span><span class="token plain"> app</span><span class="token punctuation" style=color:#393A34>.</span><span class="token method function property-access" style=color:#d73a49>waitFor</span><span class="token punctuation" style=color:#393A34>(</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword" style=color:#00009f>async</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token arrow operator" style=color:#393A34>=></span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword control-flow" style=color:#00009f>await</span><span class="token plain"> app</span><span class="token punctuation" style=color:#393A34>.</span><span class="token method function property-access" style=color:#d73a49>expectTexts</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>[</span><span class="token string" style=color:#e3116c>"Logos Calculator (C++ backend)"</span><span class="token punctuation" style=color:#393A34>]</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"> </span><span class="token literal-property property" style=color:#36acaa>timeout</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token number" style=color:#36acaa>15000</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token literal-property property" style=color:#36acaa>interval</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token number" style=color:#36acaa>500</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token literal-property property" style=color:#36acaa>description</span><span class="token operator" style=color:#393A34>:</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"UI to load"</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>}</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>}</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token function" style=color:#d73a49>test</span><span class="token punctuation" style=color:#393A34>(</span><span class="token string" style=color:#e3116c>"calc_ui_cpp: operation buttons visible"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>async</span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>(</span><span class="token parameter">app</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain"> </span><span class="token arrow operator" style=color:#393A34>=></span><span class="token plain"> </span><span class="token punctuation" style=color:#393A34>{</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"> </span><span class="token keyword control-flow" style=color:#00009f>await</span><span class="token plain"> app</span><span class="token punctuation" style=color:#393A34>.</span><span class="token method function property-access" style=color:#d73a49>expectTexts</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>[</span><span class="token string" style=color:#e3116c>"Add"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"Multiply"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"Factorial"</span><span class="token punctuation" style=color:#393A34>,</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"Fibonacci"</span><span class="token punctuation" style=color:#393A34>]</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token punctuation" style=color:#393A34>}</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token function" style=color:#d73a49>run</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token punctuation" style=color:#393A34>;</span><br/></div></code></pre></div></div>
</li>
<li class="">
<p>Stage the test file and run the hermetic CI test:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">git add tests/</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">nix build .#integration-test -L</span><br/></div></code></pre></div></div>
<p>The <code>integration-test</code> output launches <code>logos-standalone-app</code> with <code>QT_QPA_PLATFORM=offscreen</code> (no display needed), connects to the QML inspector, and runs all <code>.mjs</code> files in <code>tests/</code>.</p>
</li>
<li class="">
<p>To run tests interactively against an already-running app, build the test framework and run the app and tests in separate terminals:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">nix build .#test-framework -o result-mcp</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">nix run . # terminal 1 — app with inspector on :3768</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">node tests/ui-tests.mjs # terminal 2</span><br/></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=troubleshooting-the-c-ui-module-build>Troubleshooting the C++ UI module build<a href=#troubleshooting-the-c-ui-module-build class=hash-link aria-label="Direct link to Troubleshooting the C++ UI module build" title="Direct link to Troubleshooting the C++ UI module build" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=the-plugin-fails-to-load-at-runtime-with-no-clear-error>The plugin fails to load at runtime with no clear error<a href=#the-plugin-fails-to-load-at-runtime-with-no-clear-error class=hash-link aria-label="Direct link to The plugin fails to load at runtime with no clear error" title="Direct link to The plugin fails to load at runtime with no clear error" translate=no></a></h3>
<p>Confirm the <code>Q_PLUGIN_METADATA</code> IID and <code>Q_DECLARE_INTERFACE</code> macro in <code>calc_ui_cpp_interface.h</code> both use <code>CalcUiCppInterface_iid</code>. A mismatch causes silent load failures.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=linker-errors-during-nix-build>Linker errors during <code>nix build</code><a href=#linker-errors-during-nix-build class=hash-link aria-label="Direct link to linker-errors-during-nix-build" title="Direct link to linker-errors-during-nix-build" translate=no></a></h3>
<p>Confirm <code>../logos-calc-module/lib/libcalc.so</code> for Linux (or <code>.dylib</code> on macOS) exists and that <code>flake.lock</code> was updated with <code>--override-input calc_module path:../logos-calc-module</code>. A stale or placeholder lock file is the most common cause.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=dev_qml_path-does-not-seem-to-take-effect><code>DEV_QML_PATH</code> does not seem to take effect<a href=#dev_qml_path-does-not-seem-to-take-effect class=hash-link aria-label="Direct link to dev_qml_path-does-not-seem-to-take-effect" title="Direct link to dev_qml_path-does-not-seem-to-take-effect" translate=no></a></h3>
<p>Confirm the path points at the directory containing <code>Main.qml</code> directly — not a parent directory. The host looks for the basename from <code>"view"</code> in <code>metadata.json</code> inside the directory you provide.</div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="row margin-top--sm theme-doc-footer-edit-meta-row"><div class="col noPrint_WFHX"><a href=https://github.com/logos-co/logos-docs/tree/main/docs/core/build-modules/build-a-logos-cpp-ui-module.md target=_blank rel="noopener noreferrer" class=theme-edit-this-page><svg fill=currentColor height=20 width=20 viewBox="0 0 40 40" class=iconEdit_Z9Sw aria-hidden=true><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"/></g></svg>Edit this page</a></div><div class="col lastUpdated_JAkA"></div></div></footer></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href=/core/build-modules/wrap-a-c-library-as-a-logos-core-module><div class=pagination-nav__sublabel>Previous</div><div class=pagination-nav__label>Wrap a C library as a Logos module</div></a><a class="pagination-nav__link pagination-nav__link--next" href=/core/build-modules/install-and-load-a-module-in-logos-basecamp><div class=pagination-nav__sublabel>Next</div><div class=pagination-nav__label>Install and load a module in Logos Basecamp</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href=#what-to-expect class="table-of-contents__link toc-highlight">What to expect</a><li><a href=#step-1-scaffold-the-project class="table-of-contents__link toc-highlight">Step 1: Scaffold the project</a><li><a href=#step-2-configure-the-module-metadata class="table-of-contents__link toc-highlight">Step 2: Configure the module metadata</a><li><a href=#step-3-define-the-remote-interface class="table-of-contents__link toc-highlight">Step 3: Define the remote interface</a><li><a href=#step-4-write-the-interface-header class="table-of-contents__link toc-highlight">Step 4: Write the interface header</a><li><a href=#step-5-configure-the-cmake-build class="table-of-contents__link toc-highlight">Step 5: Configure the CMake build</a><li><a href=#step-6-write-the-c-backend-plugin class="table-of-contents__link toc-highlight">Step 6: Write the C++ backend plugin</a><li><a href=#step-7-write-the-qml-view class="table-of-contents__link toc-highlight">Step 7: Write the QML view</a><ul><li><a href=#step-75-use-the-logos-design-system-in-your-qml-optional class="table-of-contents__link toc-highlight">Step 7.5: Use the Logos Design System in your QML (Optional)</a></ul><li><a href=#step-8-configure-the-nix-flake class="table-of-contents__link toc-highlight">Step 8: Configure the Nix flake</a><li><a href=#step-9-build-and-run-the-module class="table-of-contents__link toc-highlight">Step 9: Build and run the module</a><li><a href=#step-10-update-view-with-live-reloading-optional class="table-of-contents__link toc-highlight">Step 10: Update view with live reloading (Optional)</a><li><a href=#step-11-add-ui-integration-tests-optional class="table-of-contents__link toc-highlight">Step 11: Add UI integration tests (Optional)</a><li><a href=#troubleshooting-the-c-ui-module-build class="table-of-contents__link toc-highlight">Troubleshooting the C++ UI module build</a><ul><li><a href=#the-plugin-fails-to-load-at-runtime-with-no-clear-error class="table-of-contents__link toc-highlight">The plugin fails to load at runtime with no clear error</a><li><a href=#linker-errors-during-nix-build class="table-of-contents__link toc-highlight">Linker errors during <code>nix build</code></a><li><a href=#dev_qml_path-does-not-seem-to-take-effect class="table-of-contents__link toc-highlight"><code>DEV_QML_PATH</code> does not seem to take effect</a></ul></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Docs</div><ul class="footer__items clean-list"><li class=footer__item><a class=footer__link-item href=/get-started/what-is-logos>Get started</a></ul></div><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Community</div><ul class="footer__items clean-list"><li class=footer__item><a href=https://github.com/logos-co/logos-docs target=_blank rel="noopener noreferrer" class=footer__link-item>GitHub<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a></ul></div></div><div class="footer__bottom text--center"><div class=footer__copyright>Copyright © 2026 Logos. Built with Docusaurus.</div></div></div></footer></div></body>