Hitokage
Hitokage

Reputation: 803

Implementing logic of .ui file in .qml using alias and C++ integration

I am trying to connect the C++ class with QML but I am not able to implement the logic in separate qml file. When I add the functionality directly in ui.qml file it works but I get the warning:

Functions are not supported in a Qt Quick UI form

I have tried using alias but for some reason it's not working. Here is the code:

ReasonsForm.ui.qml:

import QtQuick 2.4
//import io.qt.UserDataProvider 1.0

MenuPage {
id: reasonsPage
property alias myReasons: myReasons

title: qsTrId("reasons")

Description {
    id: reasonsText
    text: qsTrId("reasons-text")
    anchors.bottomMargin: 150
}

//UserDataProvider{id:dataProvider}

MenuTextArea {
    id: myReasons
    text: qsTrId("aa")
    anchors.horizontalCenter: reasonsText.horizontalCenter
    anchors.top: reasonsText.bottom
    width: reasonsText.width
    //this actually works despite the warnings
    //onEditingFinished: dataProvider.saveInput("myReasons", text) 
}

ReasonsForm.qml:

import QtQuick 2.4
import io.qt.UserDataProvider 1.0

ReasonsForm {
    UserDataProvider{id:dataProvider}

    myReasons{
        onEditingFinished: dataProvider.saveInput("myReasons", text)
    }
}

The compiler doesn't whine about anything but the method from dataProvider is not being called at all. Any help is much appreciated.

EDIT: I found a workaround but it's still not explaining why the code is not working. The way to make it work without qml file is adding

Connections {   
        target: myReasons
        onEditingFinished: dataProvider.saveInput("myReasons", myReasons.text)
    }

to the ui file. I'd like to separate the logic from the ui though.

EDIT II: Am I misunderstanding something? It seems like aliases are not working at all for me. Here is a simple example that's not doing anything (the button does nothing): enter image description here

Upvotes: 0

Views: 1095

Answers (2)

Hitokage
Hitokage

Reputation: 803

I was able to fix it after all. The problem was that I assumed that when having ui.qml and .qml file, they were already connected (nameForm.ui.qml and name.qml). What needs to be done is to use the .qml file to display the elements and put the .ui.qml inside so all I need to do in my case is to display/include the ReasonsForm.qml file where I want the content of ui file too since ui is already displayed in qml like this:

ReasonsForm {...

I was displaying ReasonsForm.ui.qml assuming that this is the graphic interface which is supposed to be used as the main element to display in main.qml or stack layout and ReasonsForm.qml just the additional logic. What needs to be displayed first is however the qml.

Upvotes: 1

Dmitry
Dmitry

Reputation: 2158

Here is a full example for using C++ in QML. main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import Proxy 1.0

Window {
   visible: true
   width: 640
   height: 480
   title: qsTr("Hello World")

   Proxy {
      id : proxy
   }

   Component.onCompleted: {
      var test = "Hello C++ from QML";
      proxy.call( test );
   }
}

proxy.h

#ifndef _proxy_h_
#define _proxy_h_

#include <QObject>
#include <QVariant>

class Proxy : public QObject
{
   Q_OBJECT

public :
   Proxy();
   virtual ~Proxy() {}

   Q_INVOKABLE void call( QVariant );
};

#endif

proxy.cpp

#include "proxy.h"
#include <QGuiApplication>
#include <QQmlEngine>

Proxy::Proxy() {}

void Proxy::call( QVariant in )
{
   qInfo("C++ : %s", in.toString().toStdString().c_str());
}

static void registerProxy()
{
   qmlRegisterType<Proxy>("Proxy", 1, 0, "Proxy");
}

Q_COREAPP_STARTUP_FUNCTION(registerProxy);

CMakeLists.txt

cmake_minimum_required(VERSION 3.1)

project(test_proxy LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt5 COMPONENTS Core Quick REQUIRED)

add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc" proxy/proxy.h proxy/proxy.cpp )
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick)

Upvotes: 0

Related Questions