Ubuntu – Ubuntu Touch App with Simple UI (QMake) – how to connect C++ to QML

application-developmentcprogrammingubuntu-sdkubuntu-touch

I've noticed that the Ubuntu SDK now has a template for an 'App with Simple UI (QMake)'. This creates a C++ Ubuntu application project with a sample UI containing a Label and a Button (Needs a 15.04 Kit).

What I don't understand is how to make the QML user interface communicate with the C++ code. As far as I can tell the main.qml file does not connect to the C++ code.

I'm trying to port the MythMote app to Ubuntu Touch (see also my earlier post How to create an Ubuntu Touch app with a C++ backend and a QML interface) and have a C++ application that works as a desktop application (code below). For the Ubuntu Touch app I need a QML interface to interact with the C++ code. In short: the user clicks a button on the QML interface which is connected to a C++ slot that sends a text message to a the MythMote port (let's say: socket->write(key up\r\n")).

Can someone give me a tip on how to implement this? I cannot find a working example for Ubuntu Touch.

Below is the code (not winning a beauty contest):

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QDebug>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:

    void on_right_clicked();
    void on_left_clicked();
    void on_info_clicked();
    void on_up_clicked();
    void on_guide_clicked();
    void on_square_clicked();
    void on_cancel_clicked();
    void on_down_clicked();
    void on_menu_clicked();
    void on_tv_plus_clicked();
    void on_tv_back_clicked();
    void on_tv_minus_clicked();
    void on_rec_clicked();
    void on_stop_clicked();
    void on_pause_clicked();
    void on_play_clicked();
    void on_skipbk_clicked();
    void on_rw_clicked();
    void on_ff_clicked();
    void on_skipfw_clicked();
    void on_speaker_plus_clicked();
    void on_speaker_off_clicked();
    void on_speaker_minus_clicked();

private:
    Ui::MainWindow *ui;

private:
    QTcpSocket *socket;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    socket = new QTcpSocket(this);
    socket->connectToHost("192.168.178.23",6546);
    if(socket->waitForConnected(3000))
        ui->statusBar->showMessage("connected");
    else
        ui->statusBar->showMessage("not connected");
}

MainWindow::~MainWindow()
{
    socket->close();
    delete ui;
}

void MainWindow::on_info_clicked()
{
    socket->write("key i\r\n");
}

void MainWindow::on_up_clicked()
{
    socket->write("key up\r\n");
}

void MainWindow::on_guide_clicked()
{
    socket->write("key s\r\n");
}

void MainWindow::on_left_clicked()
{
    socket->write("key left\r\n");
}

void MainWindow::on_square_clicked()
{
    socket->write("key enter\r\n");
}

void MainWindow::on_right_clicked()
{
    socket->write("key right\r\n");
}

void MainWindow::on_cancel_clicked()
{
    socket->write("key escape\r\n");
}

void MainWindow::on_down_clicked()
{
    socket->write("key down\r\n");
}

void MainWindow::on_menu_clicked()
{
    socket->write("key m\r\n");
}

void MainWindow::on_tv_plus_clicked()
{
    socket->write("play channel up\r\n");
}

void MainWindow::on_tv_back_clicked()
{
    socket->write("key h\r\n");
}

void MainWindow::on_tv_minus_clicked()
{
    socket->write("play channel down\r\n");
}

void MainWindow::on_speaker_plus_clicked()
{
    socket->write("key ]\r\n");
}

void MainWindow::on_speaker_off_clicked()
{
    socket->write("key |\r\n");
}

void MainWindow::on_speaker_minus_clicked()
{
    socket->write("key []\r\n");
}

void MainWindow::on_rec_clicked()
{
    socket->write("key r\r\n");
}

void MainWindow::on_stop_clicked()
{
    socket->write("play stop\r\n");
}

void MainWindow::on_pause_clicked()
{
    socket->write("play speed pause\r\n");
}

void MainWindow::on_play_clicked()
{
    socket->write("play speed normal\r\n");
}

void MainWindow::on_skipbk_clicked()
{
    socket->write("key home\r\n");
}

void MainWindow::on_rw_clicked()
{
    socket->write("play seek backward\r\n");
}

void MainWindow::on_ff_clicked()
{
    socket->write("play seek forward\r\n");
}

void MainWindow::on_skipfw_clicked()
{
    socket->write("key end\r\n");
}

Best Answer

When starting a new project, you need to select one of the "QML App with C++ plugin" templates:

enter image description here

I personally prefer CMake over qmake, but either one will accomplish the same thing.

When the new project wizard completes, you will end up with an application consisting of a QML interface and a QML plugin written in C++. It also serves as a functional example that demonstrates how to invoke slots in QObject classes and pass information back to QML code.

Related Question