# Industrial Systems Design and Integration

# First Class - 21/07/2020

Frazer will give the first two weeks of class being based on Qt and LabView.

# Timer project on Qt Console Application

First create a QT Console Application:



Then Add a class to the project



TIP

If using Cmake remember to include the class h and cpp file to the Cmake file.


delay.h

#ifndef DELAY_H
#define DELAY_H

#include <QObject>
#include <QTimer>
#include <iostream>

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

    void start(const float &time);

public slots:
    void slot_timerElapsed();

private:
    QTimer *timer;

signals:
    void sig_quit();

public slots:
};

#endif // DELAY_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

delay.cpp

#include "delay.h"

delay::delay(QObject *parent) : QObject(parent)
{
    timer = new QTimer();

    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(slot_timerElapsed()));
}

void delay::start(const float &time)
{
    std::cout << "Timer Started! " << std::endl;
    timer->setSingleShot(true);
    timer->start(time);
}

void delay::slot_timerElapsed()
{
    std::cout << "Timer Elapsed!" << std::endl;

    emit sig_quit();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

main.cpp

#include <QCoreApplication>
#include <QObject>

#include "delay.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    delay *d = new delay();

    QObject::connect(d, SIGNAL(sig_quit()), &a, SLOT(quit()));

    d->start(5000);

    return a.exec();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Output:

Timer Started!
Timer Elapsed!
Press <RETURN> to close this window...
1
2
3

The explanation for this program is this:

  1. Looking at the main.cpp in the main function we create an QCoreApplication a.

  2. Then we create a delay instance d. d is an instance of the method delay.

  3. We connect the SIGNAL sig_quit() to the SLOT quit() in the program. So when the SIGNAL is sent the application quits.

  4. we start d and pass the time value of 5000ms

  5. The timer starts and cout Timer Started, then goes on one shot until the time is out.

  6. Because the delay method of the delay function links the timeout of the timer to the function slot_timerElapsed(), When the time is out the slot_timerElapsed() is trigged.

  7. the slot_timerElapsed() function cout Timer Elapsed and emit the SIGNAL sig_quit()

  8. the sig_quit() SIGNAL triggers the SLOT quit() and the application a closes.

# Class 2 - 23/07/2020

TIP

Pay attention to data type when connecting slots in Qt

# Serial Communication

Now we are going to make a program that sends data to the serial port in the arduino:

main.cpp

#include <QCoreApplication>

#include <serial.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Serial *s = new Serial();

    QObject::connect(s, SIGNAL(sig_quit()), &a, SLOT(quit()));

    s->open("COM6");

    s->write("Hello world!");

    return a.exec();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

TIP

On the CMakeLists file we have to include the find_package(Qt5SerialPort) and target_link_libraries(Serial_PROJECT Qt5::SerialPort)

CMake file















 







 

cmake_minimum_required(VERSION 3.5)

project(Serial_PROJECT LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt5Core)
find_package(Qt5SerialPort)

add_executable(Serial_PROJECT
  main.cpp
  serial.h
  serial.cpp
)
target_link_libraries(Serial_PROJECT Qt5::Core)
target_link_libraries(Serial_PROJECT Qt5::SerialPort)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

serial.h

#ifndef SERIAL_H
#define SERIAL_H

#include <QObject>
#include <QtSerialPort>

#include <iostream>

class Serial : public QObject
{
    Q_OBJECT
public:
    explicit Serial(QObject *parent = nullptr);

    void open(const QString &name);
    void write(const QString &message);

signals:

    void sig_quit();

private slots:

    void slot_messageWritten();

private:
    QSerialPort *serialPort;

};

#endif // SERIAL_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

serial.cpp

TIP

qint64







 






































#include "serial.h"

Serial::Serial(QObject *parent) : QObject(parent)
{
    serialPort = new QSerialPort();

    QObject::connect(serialPort, SIGNAL(bytesWritten(qint64)), this, SLOT(slot_messageWritten()));
}

void Serial::open(const QString &name)
{
    serialPort->setPortName(name);
    serialPort->setBaudRate(115200);
    serialPort->setDataBits(QSerialPort::Data8);
    serialPort->setParity(QSerialPort::NoParity);
    serialPort->setStopBits(QSerialPort::OneStop);

    if(!serialPort->isOpen())
    {
        serialPort->close();
    }
    std::cout << "Serial Port " << name.toStdString() << "opened!" << std::endl;

    serialPort->open(QIODevice::ReadWrite);
}

void Serial::write(const QString &message)
{
    std::cout << "Message: " << message.toStdString()  << std::endl;

    int bytesWritten = serialPort->write(message.toUtf8());

    std::cout << "Bytes written: " << bytesWritten << std::endl;
}

void Serial::slot_messageWritten()
{
    std::cout << "Serial Port closed!" << std::endl;

    serialPort->close();

    emit sig_quit();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# Server

main.cpp

#include <QCoreApplication>
#include <server.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Server *s = new Server();

    QObject::connect(s, SIGNAL(sig_quit()),
                     &a, SLOT(quit()));

    return a.exec();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

CMake

cmake_minimum_required(VERSION 3.5)

project(Server LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt5Core)
find_package(Qt5Network)

add_executable(Server
  main.cpp
  server.h
  server.cpp
)
target_link_libraries(Server Qt5::Core)
target_link_libraries(Server Qt5::Network)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

server.h

#ifndef SERVER_H
#define SERVER_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>

#include <iostream>

class Server : public QObject
{
    Q_OBJECT
public:
    explicit Server(QObject *parent = nullptr);

signals:
    void sig_quit();

public slots:
    void slot_acceptConnection();
    void slot_readMessage();

private:
    QTcpServer *messageServer;
    QTcpSocket *socket;

};

#endif // SERVER_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

server.cpp

#include "server.h"

Server::Server(QObject *parent) : QObject(parent)
{
    messageServer = new QTcpServer();
    socket = new QTcpSocket();

    QObject::connect(messageServer, SIGNAL(newConnection()),
                     this, SLOT(slot_acceptConnection()));

    messageServer->listen(QHostAddress("127.0.0.1"), 9601);
}

void Server::slot_acceptConnection()
{
    socket = messageServer->nextPendingConnection();

    QObject::connect(socket, SIGNAL(readyRead()),
                     this, SLOT(slot_readMessage()));
}

void Server::slot_readMessage()
{
    QByteArray buffer;

    buffer = socket->readAll();

    int bytesRead = buffer.length();

    std::cout << "Message: " << buffer.toStdString() << std::endl;

    std::cout << "Bytes read: " << bytesRead << std::endl;

    messageServer->close();

    emit sig_quit();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# Client

main.cpp

#include <QCoreApplication>

#include "client.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    client *c = new client();

    QObject::connect(c, SIGNAL(sig_quit()),
                     &a, SLOT(quit()));

    c->open("127.0.0.1", 9601);

    c->write("Hello World");

    return a.exec();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Cmake

cmake_minimum_required(VERSION 3.5)

project(client LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt5Core)
find_package(Qt5Network)

add_executable(client
  main.cpp
  client.h
  client.cpp
)
target_link_libraries(client Qt5::Core)
target_link_libraries(client Qt5::Network)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

client.h

#ifndef CLIENT_H
#define CLIENT_H

#include <QObject>
#include <QTcpSocket>
#include <iostream>

class client : public QObject
{
    Q_OBJECT
public:
    explicit client(QObject *parent = nullptr);

    void open(const QString &ipAdress, const int &port);
    void write(const QString &message);

signals:
    void sig_quit();

private slots:
    void slot_onConnection();
    void slot_messageWritten();

private:
    QTcpSocket * socket;
};

#endif // CLIENT_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

client.cpp

#include "client.h"

client::client(QObject *parent) : QObject(parent)
{
    socket = new QTcpSocket();

    QObject::connect(socket, SIGNAL(connected()),
                     this, SLOT(slot_onConnection()));

    QObject::connect(socket, SIGNAL(bytesWritten(qint64)),
                     this, SLOT(slot_messageWritten()));
}

void client::open(const QString &ipAdress, const int &port)
{
    socket->connectToHost(ipAdress, port);
}

void client::write(const QString &message)
{
    std::cout << "Message: " << message.toStdString() << std::endl;

    int bytesWritten = socket->write(message.toUtf8());

    std::cout << "Bytes written: " << bytesWritten << std::endl;
}

void client::slot_onConnection()
{
    std::cout << "Connected to host" << std::endl;
}

void client::slot_messageWritten()
{
    socket->close();

    emit sig_quit();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# Interaction between Server and Client

Server:

Message: Hello World
Bytes read: 11
1
2

Client:

Message: Hello World
Bytes written: 11
Connected to host
1
2
3

# Class 3 - 28/07/2020

# Simple UI with timer control

First let's build a simple ui



Then it will delay for 5 seconds before close the application

main.cpp

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

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

    delay *d = new delay();

    QObject::connect(&w, SIGNAL(waitNow(const float&)),
                     d, SLOT(slot_startTimer(const float&)));

    QObject::connect(d, SIGNAL(sig_quit()), &a, SLOT(quit()));

    w.show();

    return a.exec();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

delay.h

#ifndef DELAY_H
#define DELAY_H

#include <QTimer>
#include <QObject>
#include <QDebug>

class delay : public QObject
{
    Q_OBJECT
public:
    explicit delay(QObject *parent = nullptr);

    void start(const float &time);

signals:
    void sig_quit();

public slots:
    void slot_startTimer(const float &time);

    void slot_timerElapsed();

private:
    QTimer *timer;
};

#endif // DELAY_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

delay.cpp

#include "delay.h"

delay::delay(QObject *parent) : QObject(parent)
{
    timer = new QTimer();

    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(slot_timerElapsed()));
}

void delay::start(const float &time)
{
    qDebug() << "Timer Started!";

    timer->setSingleShot(true);
    timer->start(time);
}

void delay::slot_startTimer(const float &time)
{
    start(time);
}

void delay::slot_timerElapsed()
{
    qDebug() << "Timer Elapsed!";

    emit sig_quit();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

signals:
    void waitNow(const float &time);


private slots:
    void on_waitButton_clicked();

    void on_actionQuit_triggered();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

mainwindow.cpp

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

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_waitButton_clicked()
{
    float delayTimer{5000};
    emit waitNow(delayTimer);
}

void MainWindow::on_actionQuit_triggered()
{
    QApplication::quit();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


# OpenCV Example

The Cmake file. It's important to use a MSVC kit to build, because the OpenCV library built was built with MSVC. To use the MingW we have to compile Opencv with MingW from the github source.

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(OpenCV LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
# Check http://doc.qt.io/qt-5/deployment-android.html for more information.
# They need to be set before the find_package(Qt5 ...) call.

#if(ANDROID)
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
#    if (ANDROID_ABI STREQUAL "armeabi-v7a")
#        set(ANDROID_EXTRA_LIBS
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)
#    endif()
#endif()

find_package(Qt5 COMPONENTS Widgets REQUIRED)
SET("OpenCV_DIR" "C:/opencv")

find_package(OpenCV REQUIRED)

if(ANDROID)
  add_library(OpenCV SHARED
    main.cpp
    mainwindow.cpp
    mainwindow.h
    mainwindow.ui
    algorithm.cpp
    algorithm.h
  )
else()
  add_executable(OpenCV
    main.cpp
    mainwindow.cpp
    mainwindow.h
    mainwindow.ui
    algorithm.cpp
    algorithm.h
  )
endif()

target_link_libraries(OpenCV PRIVATE Qt5::Widgets ${OpenCV_LIBS})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

For this project we are going to create a simple class that will call for an algorithm() function. This function will create a namedWindow with a "Hello World" title and wait to be closed.

algorithm.h

#ifndef ALGORITHM_H
#define ALGORITHM_H

#include <opencv2/opencv.hpp>

class algorithm
{
public:
    algorithm();
};

#endif // ALGORITHM_H
1
2
3
4
5
6
7
8
9
10
11
12

algorithm.cpp

#include "algorithm.h"

algorithm::algorithm()
{
    cv::namedWindow("Hello World");
    cv::waitKey(0);
}
1
2
3
4
5
6
7

The main window will be there with no function, just the normal project created by Qt.