Tendo problemas ao vincular o botão QML à classe C ++

0

Primeira vez usando o Ubuntu SDK e QML. Eu passei o dia inteiro tentando descobrir isso, mas todas as soluções que cheguei estão desatualizadas ou não estão bem documentadas. Eu estou tentando descobrir como eu posso ligar meus botões no QML para funções em C ++.

Minha turma para minha função:

#include "terminal_launcher.h"
#include <QProcess>

terminal_launcher::terminal_launcher(QObject *parent) :
    QObject(parent)
{




}

void open_terminal() {
    QProcess proc;
   proc.start("gnome-terminal", QIODevice::ReadWrite);
 }

Meu terminal_launch.h

#ifndef TERMINAL_LAUNCHER_H
#define TERMINAL_LAUNCHER_H

#include <QObject>

class terminal_launcher : public QObject
{
    Q_OBJECT
public:
    explicit terminal_launcher(QObject *parent = 0);

signals:

public slots:

};

#endif // TERMINAL_LAUNCHER_H

Meu main.cpp

    #include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <QString>
#include <QProcess>
#include <QDebug>
//#include "launcher.h"
//#include <QtQml>


int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

        QQuickView view;
        view.setSource(QUrl(QStringLiteral("qrc:///main.qml")));
        view.setResizeMode(QQuickView::SizeRootObjectToView);
   //   qmlRegisterType<Launcher>(uri, 1, 0, "Launcher");
        view.show();

        return app.exec();

}

e finalmente meu main.qml

    import QtQuick 2.0
import Ubuntu.Components 1.1

/*!
    \brief MainView with a Label and Button elements.
*/
import QtQuick.LocalStorage 2.0
import QtQuick.Controls 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Window 2.1
import QtQuick.Layouts 1.1
import Ubuntu.Components.Popups 0.1
MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "com.ubuntu.dev.product.productname"

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(100)
    height: units.gu(75)

    Page {
        y: 76
        anchors.rightMargin: 0
        anchors.bottomMargin: 0
        anchors.leftMargin: 0
        title: "Home"
        Column {
            enabled: true
            anchors.rightMargin: 16
            anchors.bottomMargin: 0
            anchors.leftMargin: 16
            anchors.topMargin: 16
            spacing: units.gu(1)
            anchors {
                margins: units.gu(2)
                fill: parent
            }
        }

        Item {
            id: item1
            x: 470
            y: 327
            width: 199
            height: 50
            anchors {
               top: parent.top
               left: parent.left
               right: parent.right
               bottom: parent.bottom
             }
            Action {
                  id: action1
                  text: "Click me"
                  onTriggered: print("action!")
                  iconName: "compose"
              }

            Button {
             //   signal openTerminal()
                id: test_btn
                x: 25
                y: 8
                width: 150
                height: 35
                text: i18n.tr("test")
                checked: false
                iconSource: qsTr("")
                //action: ""

                objectName: "button"
            //   onClicked: print("hmm");
            }
        }



    }
}

Qualquer ajuda com isso seria muito apreciada! Obrigado :)

    
por aqq 11.01.2015 / 04:34

1 resposta

0

Pelo que entendi, você só pode importar objetos, não funções nuas, para o QML a partir do C ++. Portanto, você precisa transformar sua função open_terminal em um método de terminal_launcher , adicionar um objeto terminal_launcher ao seu arquivo QML e chamar seu método open_terminal no local apropriado.

Uma adaptação do seu código segue. Observe que renomei terminal_launcher para TerminalLauncher para corresponder ao estilo Qt.

terminal_launcher.h

#ifndef TERMINAL_LAUNCHER_H
#define TERMINAL_LAUNCHER_H

#include <QObject>
#include <QProcess>

class TerminalLauncher : public QObject
{
    Q_OBJECT

public:
    Q_INVOKABLE void open_terminal();

private:
    QProcess proc;
};

#endif // TERMINAL_LAUNCHER_H

open_terminal agora é um método. Ele é marcado como Q_INVOKABLE para que possa ser usado a partir do QML. proc foi transformada em uma propriedade de instância para evitar que ela seja coletada como lixo quando o método termina de ser executado, mas o processo filho ainda está por aí.

terminal_launcher.cpp

#include "terminal_launcher.h"

void TerminalLauncher::open_terminal() {
    this->proc.start("gnome-terminal", QIODevice::ReadWrite);
}

main.cpp

#include <QGuiApplication>
#include <QQuickView>
#include <QString>
#include <QtQml>
#include "terminal_launcher.h"


int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    qmlRegisterType<TerminalLauncher>("com.example.launcher", 1, 0, "Launcher");

    QQuickView view;
    view.setSource(QUrl("main.qml"));
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.show();

    return app.exec();
}

A chamada de qmlRegisterType é crítica, pois permite que a classe TerminalLauncher seja instanciada no QML. O primeiro argumento é o nome do módulo que deve ser importado. O segundo e o terceiro são os números das versões principais e secundárias. O quarto argumento é o nome pelo qual esta classe é conhecida no QML. Você provavelmente quer torná-lo o mesmo que é em C ++, para evitar ficar louco, mas eu fiz diferente apenas para mostrar que pode ser.

main.qml

import QtQuick 2.0
import QtQuick.Controls 1.1
import com.example.launcher 1.0

Rectangle {
    width: 200
    height: 51

    Launcher {
        id: launcher
    }

    Button {
        x: 25
        y: 8
        width: 150
        height: 35
        text: "test"
        onClicked: launcher.open_terminal();
    }
}

Simplifiquei bastante isso para mostrar as partes relevantes. Observe que eu instancio um objeto Launcher e, em seguida, chamo seu método open_terminal quando o botão é clicado.

termlaunch.pro

CONFIG += qt
QT += quick
HEADERS = terminal_launcher.h
SOURCES = main.cpp terminal_launcher.cpp
TARGET = termlaunch

Este arquivo de projeto instrui o qmake a criar um binário chamado termlaunch . Todos esses arquivos devem ir no mesmo diretório.

    
por Robert Schroll 11.01.2015 / 21:24