\documentclass{beamer}
% Fix some Beamer warnings, see
% http://texblog.net/latex-archive/presentations/beamer-warnings/
\let\Tiny=\tiny
\usepackage[utf8]{inputenc}

\mode<presentation>
\usetheme{Bootlin}

\title{Using Qt for non-graphical applications}
\author{Thomas Petazzoni}
\institute{Bootlin}

\usepackage{eurosym}
\usepackage{multicol}

\begin{document}

%% Title %%
\begin{frame}{FOSDEM 2012}
  \begin{columns}[b]
   \column{0.7\textwidth}
     \huge
     {\em Qt} for non-graphical applications\\
     \vspace{1cm}
     \normalsize
     Thomas Petazzoni\\
     {\bf Bootlin}\\
     {\em thomas.petazzoni@bootlin.com}
     \column{0.3\textwidth}
     \includegraphics[height=4cm]{qt-logo.pdf}
   \end{columns}
\end{frame}

\begin{frame}{Thomas Petazzoni}
  \begin{itemize}
  \item Embedded Linux engineer and trainer at Bootlin since
    2008
    \begin{itemize}
    \item Embedded Linux development: kernel and driver
      development, system integration, boot time and power
      consumption optimization, consulting, etc.
    \item Embedded Linux, driver development and Android system
      development trainings, with materials freely available under a
      Creative Commons license.
    \item \url{http://www.bootlin.com}
    \end{itemize}
  \item Major contributor to Buildroot, an open-source, simple and
    fast embedded Linux build system
  \item Living in Toulouse, south west of France
  \end{itemize}
\end{frame}

\begin{frame}{Agenda}

\begin{itemize}
  \item Context and problem statement
  \item Possible solutions
  \item Usage of Qt
    \begin{itemize}
      \item Why Qt ?
      \item The signal/slot mechanism
      \item Usage of timers
      \item Interaction with serial ports
      \item Interaction with sub-processes
      \item Interaction with network
      \item Interaction with Linux Input devices
    \end{itemize}
  \item Conclusion
\end{itemize}

\end{frame}

\begin{frame}{Context and problem statement: hardware}

\begin{itemize}
  \item ARM platform
    \begin{itemize}
      \item AT91-based
      \item 400 MHz
      \item 64 MB of RAM
      \item 128 MB Flash
      \item {\bf No screen !}
    \end{itemize}

  \item Platform with multiple peripherals
    \begin{itemize}
    \item GSM modem
    \item active RFID reader
    \item passive RFID reader
    \item GPS
    \item USB barcode reader
    \end{itemize}

\end{itemize}

\end{frame}

\begin{frame}{Context and problem statement: application}

Develop an application that:

\begin{itemize}
  \item Communicates with an HTTP server over the GSM modem and/or a
    wired Ethernet connection
  \item Fetches an XML configuration from HTTP and parses it
  \item Handles events from RFID readers (serial port or Ethernet
    based) and USB barcode readers
  \item Manages timers per object seen through RFID (as many timers as
    objects seen)
  \item Controls the GSM modem to establish data connection and
    send/receive SMS
  \item Applies actions depending on the configuration and events
  \item Informs the HTTP server of events and actions happening
  \item Remains under a proprietary license
\end{itemize}

\end{frame}

\begin{frame}{Possible solutions}

  \begin{itemize}
    \item Write an {\bf application in raw C}
      \begin{itemize}
      \item Use {\em libcurl} for HTTP communication
      \item Use {\em libxml2} or {\em expat} for XML parsing
      \item Manually implement, or use another library, for basic data
        structure management (linked lists, hash tables, etc.)
      \item As I don't like threads, use {\tt select()} or {\tt poll()}
        to handle events coming from the serial ports, the GSM modem,
        the network, the USB barcode reader, and the potential dozens or
        hundred of timers needed by the application to track objects.
      \end{itemize}
    \item Write {\bf a C application using {\em glib}} for event management
      and basic facilities (data structures, XML parsing, but requires
      {\em libsoup} for HTTP)
    \item Write an {\bf application in Python/Ruby}
      \begin{itemize}
      \item Quite heavy interpreter, interpreted code (no
        compilation), etc.
      \end{itemize}
    \item Application had to be developed in a short period of time,
      and had to adapt quickly to changes in the specification of its
      behaviour.
  \end{itemize}

\end{frame}

\begin{frame}{Qt features}

  \begin{itemize}

    \item Qt is a cross-platform toolkit for application development
    \item Largely used and known as a graphical widget library, but Qt
      is far more than that.

      \begin{multicols}{2}
      \begin{itemize}
      \item {\bf QtCore}, event loop with an original signal/slot mechanism, data
        structures, threads, regular expressions
      \item {\bf QtNetwork} networking (TCP, UDP clients and servers
        made easy, HTTP, FTP support)
      \item {\bf QtXml} for SAX/DOM parsing of XML files
      \item {\bf QtXmlPatterns} for XPath, XQuery, XSLT and XML schema support
      \item {\bf QtGui} for GUI widgets
      \item {\bf QtMultimedia} for low-level multimedia functionality
      \item {\bf QtOpenGL}
      \item {\bf QtOpenVG}
      \item {\bf QtScript}, an ECMAScript-based scripting engine
      \item {\bf QtSQL} to query various databases
      \item {\bf QtSvg}
      \item and more...
      \end{itemize}
      \end{multicols}

  \end{itemize}

\end{frame}

\begin{frame}{The choice of Qt}

With {\em Qt}, we have :
\begin{itemize}
  \item the benefits of a {\bf compiled language}, C++ (checks at
    compile time, slightly better performance)
  \item an {\bf ease of programming} approaching the one found in scripting
    languages such as Python or Ruby, with all the services provided
    by Qt
  \item a framework with an {\bf excellent documentation}, many
    tutorials, forums
  \item a framework for which the {\bf knowledge can be re-used} for
    other projects, in other situations
  \item a framework {\bf licensed under the LGPL}, which allows
    development and distribution of proprietary applications
\end{itemize}

Moreover :

\begin{itemize}
  \item We don't have huge performance constraints or real-time
    constraints
  \item Our platform is big enough to handle a library such as {\em
    Qt}
\end{itemize}

\end{frame}

\begin{frame}{Size of Qt}

\begin{itemize}
\item A common complaint about Qt could be its size
\item Qt is {\bf highly configurable}, and it is possible to build
  only some of the modules and for each module define which
  classes/features are included.
\item In my application, only the following modules were needed
  (binary sizes given stripped for an ARM platform)
  \begin{itemize}
    \item {\bf QtCore}, for the event loop, timers, data structures. Weighs {\bf 2.7~MB}
    \item {\bf QtNetwork}, for HTTP communication. Weighs {\bf 710~KB}
    \item {\bf QtXml}, for parsing XML configuration files received
      over the network. Weighs {\bf 200~KB}.
    \item No other dependencies besides the standard C++ library
      ({\bf 802~KB})
  \end{itemize}
\item It's certainly a few megabytes, but the {\bf ease of
  development} is so much higher that they are worth it, especially on
  a device with 128 MB of Flash and 64 MB of RAM running this single
  application.
\end{itemize}

\end{frame}

\begin{frame}[fragile]{Data structures: lists}

Super easy chained-list mechanism, much easier to use than the {\tt
  sys/queue.h} API available in C.

\begin{block}{}
\small
\begin{verbatim}
#include <QList>

QList<MyObject*> objList;

objList.append(someObj);

foreach (MyObject *obj, objList) {
   /* Do something with obj */
}

objList.removeOne(someOtherObj);

myObj = objList.takeFirst();
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Data structures: hash maps}

Here as well, easy to use hash maps.

\begin{block}{}
\small
\begin{verbatim}
#include <QHash>

QHash<QString, MyObject*> objMap;

QString name("someName");
objMap[name] = obj;

if (objMap.contains(name)) {
  /* Do something */
}

MyObject *obj = objMap[name];
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}{Signal/slot mechanism}

\begin{itemize}
  \item The {\bf {\em signal/slot}} mechanism is a core mechanism of
    the Qt framework
    \begin{itemize}
    \item Objects can define {\bf {\em slots}}, which are functions
      called in response to a signal being received
    \item Objects can emit {\bf {\em signals}}, which are events
      optionally associated with data
    \item A signal of a given object can be {\bf connected} to one or
      more prototype-compatible slots in the same object or in other
      objects
    \end{itemize}
  \item Allows for very clean management of event propagation inside the
    application
    \begin{itemize}
    \item Makes {\tt select()} easy to use.
    \item Most Qt classes use this mechanism, and it can be used by
      the application classes as well
    \end{itemize}
\end{itemize}

\end{frame}

\begin{frame}{Signal/slot diagram}

\begin{center}
\includegraphics[width=0.7\textwidth]{signal-slot.png}
\end{center}

\end{frame}

\begin{frame}[fragile]{Signal/slot example: slot side}

A class defines a {\em public slot}, which is implemented as a regular
C++ method.

\begin{block}{}
\small
\begin{verbatim}
class Foobar : public QObject {
 Q_OBJECT
 ...
 public slots:
   void newFrameReceived(uint identifier);
 ...
};

void Foobar::newFrameReceived(uint identifier)
{
  /* Do something */
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Signal/slot example: signal side}

Another class can emit a signal, and use the {\em emit} keyword to do
so.

\begin{block}{}
\small
\begin{verbatim}
class FrameWatcher : public QObject {
 Q_OBJECT
 ...
 signals:
   void notifyFrameReceived(uint identifier);
 ...
};

void FrameWatcher::someMethod(void)
{
  uint id;
  ...
  emit notifyFrameReceived(id);
  ...
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Signal/slot example: connecting things}

\begin{itemize}
\item Connection takes place between one signal and one slot using the
  {\tt QObject::connect} method.
\item One signal can be connected to multiple slots.
\item The great thing is that the class emitting the signal does not
  need to know in advance to which signal receiver classes it will be
  connected.
\end{itemize}

\begin{block}{}
\small
\begin{verbatim}
int main(void) {
   FrameWatcher fw;
   Foobar f;

   QObject::connect(& fw, SIGNAL(notifyFrameReceived(uint)),
                    & f,  SLOT(newFrameReceived(int)));
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Timers (1/2)}

\begin{itemize}
\item In C, timers are a bit painful to use, especially when there are
  dozens or hundreds of timers in various places of the application.
\item In {\em Qt}, it's very easy and timers are naturally integrated
  with all other events in the event loop.
\end{itemize}

Simply define a {\em slot} and a {\em QTimer} object.

\begin{block}{}
\small
\begin{verbatim}
class Foobar : public QObject
{
 Q_OBJECT
 private slots:
   void timerExpired(void);
 private:
   QTimer timer;
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Timers (2/2)}

Start the timer whenever you want (here in the constructor) and your
{\em slot method} gets called every second.

\begin{block}{}
\small
\begin{verbatim}
Foobar::Foobar()
{
 connect(& timer, SIGNAL(timeout()),
         this, SLOT(timerExpired()));
 timer.start(1000);
}

void Foobar::timerExpired(void)
{
  /* Called every second */
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Spawning processes 1/2}

Very easy to spawn and control sub-processes. In our application, we
needed to control the execution of {\tt pppd} to establish GPRS data
connections.

\begin{block}{Create a process object}
\small
\begin{verbatim}
p = new QProcess();
\end{verbatim}
\end{block}

\begin{block}{Connect its termination signal}
\footnotesize
\begin{verbatim}
connect(p, SIGNAL(finished(int, QProcess::ExitStatus)),
        this, SLOT(mySubProcessDone(int, QProcess::ExitStatus)));
\end{verbatim}
\end{block}

\begin{block}{Start the process}
\small
\begin{verbatim}
p->start("mycommand");
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Spawning processes 2/2}

\begin{block}{Stop the process}
\small
\begin{verbatim}
p->terminate();
\end{verbatim}
\end{block}

\begin{block}{Notification of completion in a slot}
\small
\begin{verbatim}
void MyClass::mySubProcessDone(int, QProcess::ExitStatus)
{
  /* Do something */
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Regular expressions}

Qt has built-in support for regular expressions, there is no need for
an external library such as {\em pcre}.

\begin{block}{}
\small
\begin{verbatim}
QRegExp r("\\[([0-9A-F]{2})([0-9A-F]{6})([0-9A-F]{2})\\]");
int pos = r.indexIn(myString);
if (pos != 0) {
     qWarning("no match");
     return;
}

uint field1 = r.cap(1).toUInt(NULL, 16);
uint field2 = r.cap(2).toUInt(NULL, 16);
uint field3 = r.cap(3).toUInt(NULL, 16);
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Networking and HTTP}

Qt also has built-in support for various network protocols, including
HTTP, without the need of an external library such as {\em libcurl}.

\begin{block}{Instantiate a {\em NetworkManager}}
\small
\begin{verbatim}
nmanager = new QNetworkAccessManager();
\end{verbatim}
\end{block}

\begin{block}{Doing a POST request}
\small
\begin{verbatim}
QNetworkRequest netReq(QUrl("http://foobar.com"));

reply = nmanager->post(netReq, contents.toAscii());
connect(reply, SIGNAL(finished(void)),
        this, SLOT(replyFinished(void)));
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{TCP server (1/3)}

\begin{block}{Defining the object implementing the TCP server}
\small
\begin{verbatim}
class MyOwnTcpServer : public QObject
{
  Q_OBJECT
public:
  MyOwnTcpServer();

private slots:
  void acceptConnection(void);
  void readClient(void);

private:
  QTcpServer *srv;
};
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{TCP server (2/3)}

\begin{block}{TCP server constructor}
\small
\begin{verbatim}
MyOwnTcpServer::MyOwnTcpServer(void)
{
  srv = new QTcpServer(this);
  srv->listen(QHostAddress::any, 4242);
  connect(srv, SIGNAL(newConnection()),
          this, SLOT(acceptConnection()));
}
\end{verbatim}
\end{block}

\begin{block}{Accepting clients}
\small
\begin{verbatim}
void MyOwnTcpServer::acceptConnection(void)
{
  QTcpSocket *sk = srv->nextPendingConnection();
  connect(sk, SIGNAL(readyRead()),
          this, SLOT(readClient()));
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{TCP server (3/3)}

\begin{block}{Receiving data line by line}
\small
\begin{verbatim}
void MyOwnTcpServer::readClient(void)
{
  QTcpSocket *sk = dynamic_cast<QTcpSocket *>(sender());
  if (! sk->canReadLine())
    return;
  char buf[1024];
  sk->readLine(buf, sizeof(buf));
  /* Do some parsing with buf, emit a signal
     to another object, etc. */
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{XML Parsing}

\begin{block}{Instantiating a DOM document with file contents}
\small
\begin{verbatim}
QFile *f = new QFile();
f->open(QIODevice::ReadOnly | QIODevice::Text);

dom = new QDomDocument();
dom->setContent(f);
\end{verbatim}
\end{block}

\begin{itemize}
  \item And then, thanks to the {\tt QDomDocument}, {\tt
    QDomNodeList}, {\tt QDomNode} and {\tt QDomElement} classes, you
    can easily parse your XML data.
  \item Not much different from {\em libxml2}, but it's built into
    {\em Qt}, no need for an external library.
  \item Of course, besides the basic {\em DOM} API, there is also a
    {\em SAX} API and a special {\em stream} API.
\end{itemize}

\end{frame}

\begin{frame}{Communicating with serial ports (1/4)}

  \begin{itemize}
  \item Communicating with serial ports was essential in our application
  \item Of course, using the classical C API is possible, but we would
    like to integrate serial port communication into the {\em Qt} event
    loop
  \item The {\em QExtSerialPort} additional library makes this really
    easy.
  \item \url{http://code.google.com/p/qextserialport/}
  \end{itemize}

\end{frame}

\begin{frame}[fragile]{Communicating with serial ports (2/4)}

\begin{block}{Initialization}
\small
\begin{verbatim}
port = new QextSerialPort("/dev/ttyS3",
                          QextSerialPort::EventDriven);
port->setBaudRate(BAUD9600);
port->setFlowControl(FLOW_OFF);
port->setParity(PAR_NONE);
port->setDataBits(DATA_8);
port->setTimeout(0);
port->open(QIODevice::ReadOnly);
connect(port, SIGNAL(readyRead()),
        this, SLOT(getData()));
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Communicating with serial ports (3/4)}

\begin{block}{Receiving data in the slot method}
\small
\begin{verbatim}
void MyClass::getData(void)
{
  while (1) {
    char c;
    if (port->read(& c, 1) <= 0)
      break;

    /* Do something, like parse the received data, and
       emit a signal when something meaningful has been
       received */
  }
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}{Communicating with serial ports (4/4)}

\begin{center}
  \includegraphics[width=0.9\textwidth]{qt-serial-port.pdf}
\end{center}

\end{frame}

\begin{frame}{Using Linux input devices (1/4)}

\begin{itemize}
  \item In the project, we had to use USB barcode readers, which are
    implemented as standard USB HID devices
  \item {\em QtGui} obviously has support for a wide range of input
    devices
  \item But in {\em QtCore}, there is no dedicated infrastructure
  \item So we wanted to integrate the event notification of a Linux
    Input device into the {\em Qt} event loop
  \item This is very easy to do with {\tt QSocketNotifier}
\end{itemize}

\end{frame}

\begin{frame}[fragile]{Using Linux input devices (2/4)}

\begin{block}{Class declaration}
\small
\begin{verbatim}
class QLinuxInputDevice : public QObject
{
Q_OBJECT
public:
  QLinuxInputDevice(const QString &name);

signals:
  void onInputEvent(struct input_event ev);

private slots:
  void readyRead(void);

private:
  int fd;
  QSocketNotifier *readNotifier;
};
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Using Linux input devices (3/4)}

\begin{block}{Initialization}
\small
\begin{verbatim}
QLinuxInputDevice::QLinuxInputDevice(const QString &name)
{
  fd = ::open(fileName.toAscii(), O_RDWR | O_NONBLOCK);

  readNotifier =
    new QSocketNotifier(fd, QSocketNotifier::Read, this);

  connect(readNotifier, SIGNAL(activated(int)),
          this, SLOT(readyRead()));
}
\end{verbatim}
\end{block}

The {\tt QSocketNotifier} mechanism tells {\em Qt} to add our file
descriptor in its {\tt select()} loop and to dispatch events on this
file descriptor as {\em Qt} signals.

\end{frame}

\begin{frame}[fragile]{Using Linux input devices (4/4)}

\begin{block}{Receiving events}
\small
\begin{verbatim}
void QLinuxInputDevice::readyRead(void)
{
  struct input_event ev[64];

  while(1) {
    int sz = ::read(fd, ev, sizeof(ev));
    if (sz <= 0)
      break;
    for (int i = 0;
         i < (sz / sizeof(struct input_event));
         i++)
      emit onInputEvent(ev[i]);
  }
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Integrating Unix signals 1/2}

  We want to get a nice {\em Qt} signal when an {\em Unix} signal is
  received. The goal is to handle {\em SIGHUP} in order to reopen the
  log file (after it has been rotated by {\em logrotate}).

\begin{block}{Class definition}
\tiny
\begin{verbatim}
class QUnixSignalHandler : public QObject
{
  Q_OBJECT
public:
  QUnixSignalHandler(int signal);

signals:
  void fired(void);

private slots:
  void gotSignal(void);

private:
  int fd;
};
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Integrating Unix signals 2/2}

  To implement this, we use the {\em signalfd()} system call and a
  {\em QSocketNotifier}. Thanks to this, the Unix signal notification
  is completely integrated into {\em Qt} event loop, like all other
  events.

\begin{block}{Class implementation}
\tiny
\begin{verbatim}
QUnixSignalHandler::QUnixSignalHandler(int signal)
{
  sigset_t sigset;
  sigemptyset(& sigset);
  sigaddset(& sigset, signal);

  sigprocmask(SIG_BLOCK, &sigset, NULL);

  fd = signalfd(-1, & sigset, 0);
  if (fd < 0)
    qFatal("Bork");

  QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, this);
  connect(sn, SIGNAL(activated(int)), this, SLOT(gotSignal()));
}

void QUnixSignalHandler::gotSignal(void)
{
  struct signalfd_siginfo si;
  ::read(fd, & si, sizeof(si));
  emit fired();
}
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Usage of Unix signal integration}

  Our {\em Logger} class instantiates a {\em QUnixSignalHandler} and
  connects its {\em fired()} signal to a slot that reopens the log
  file.

\begin{block}{Example of {\em QUnixSignalHandler} usage}
\tiny
\begin{verbatim}
Logger::Logger(QString _logFile)
{
        [...]
        sigHandler = new QUnixSignalHandler(SIGHUP);
        connect(sigHandler, SIGNAL(fired()),
                this, SLOT(reOpenLogFile()));
}

void Logger::reOpenLogFile(void)
{
        [...]
}
\end{verbatim}
\end{block}
\end{frame}

\begin{frame}{Coming back to the signal/slot mechanism}

\begin{itemize}
  \item The {\em signal/slot} mechanism is really a {\bf great}
    feature of {\em Qt}
  \item It unifies all the event management into something much easier
    to use than a single, central, {\tt select()} event loop
  \item All events, such as timer expiration, communication on serial
    ports, on TCP sockets, with Linux input devices, communication
    with external process are all handled in the same way.
  \item Each class appears to do its own {\em event management},
    locally, making the code very straight-forward
  \item Allows to easily write a single-threaded application: avoids
    the need for threads and complicated mutual exclusion,
    synchronization issues, etc.
  \item A bit more difficult to manage the the GPRS modem, needed a
    moderately elaborate state machine.
\end{itemize}

\end{frame}

\begin{frame}{Building Qt applications}

  \begin{itemize}

  \item {\em Qt} comes with its own build system, called {\bf
    qmake}.
    \begin{itemize}
      \item basic and easy to use build system
      \item a {\tt .pro} file describes the project sources and
        required libraries, and a Makefile is automatically generated
        by {\em qmake}
      \item a specially-configured {\em qmake} is needed to do
        cross-compilation.
      \item \url{http://doc.qt.nokia.com/latest/qmake-manual.html}
    \end{itemize}

  \item For a more powerful build system, {\bf CMake} is definitely a
    good choice
    \begin{itemize}
      \item the one we have chosen for our project
      \item the developer writes a {\tt CMakeLists.txt} file, {\tt
        cmake} parses this file, runs the associated checks and
        generates a conventional {\em
          Makefile}
      \item \url{http://www.cmake.org}.
    \end{itemize}

  \end{itemize}

\end{frame}

\begin{frame}[fragile]{Building with {\em Cmake} : {\tt CMakeLists.txt}}

\begin{block}{}
\footnotesize
\begin{verbatim}
project(myproject)

find_package(Qt4 REQUIRED COMPONENTS QtCore QtNetwork QtXML)

set(myproject_SOURCES main.cpp file1.cpp file2.cpp file3.cpp)
set(myproject_HEADERS_MOC file1.h file2.h)
set(myproject_HEADERS file3.h)

QT4_WRAP_CPP(myproject_HEADERS_MOC_GENERATED
             ${myproject_HEADERS_MOC})

include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})

\end{verbatim}
\end{block}

Note: newer versions of {\em CMake} will make it even easier, the {\tt
  QT4\_WRAP\_CPP} call and related things due to the {\em moc}
pre-processor are done implicitly.

\end{frame}

\begin{frame}[fragile]{Building with {\em Cmake} : {\tt CMakeLists.txt}}

\begin{block}{}
\footnotesize
\begin{verbatim}
find_package(PkgConfig)
pkg_search_module(EXTSERIALPORT REQUIRED qextserialport)
link_directories(${EXTSERIALPORT_LIBRARY_DIRS})
include_directories(${EXTSERIALPORT_INCLUDE_DIRS})

add_executable(myapp ${myproject_SOURCES}
               ${myproject_HEADERS_MOC_GENERATED}
               ${myproject_HEADERS})
target_link_libraries(myapp ${QT_LIBRARIES}
                      ${EXTSERIALPORT_LIBRARIES})

install(TARGETS myapp
  RUNTIME DESTINATION bin
)
\end{verbatim}
\end{block}

See also
\url{http://developer.qt.nokia.com/quarterly/view/using_cmake_to_build_qt_projects}.

\end{frame}

\begin{frame}[fragile]{Building with {\em CMake}}

\begin{itemize}
\item Create a build directory\\{\tt mkdir build; cd build}
\item Start the configuration process\\{\tt cmake -DCMAKE\_TOOLCHAIN\_FILE=/path/to/toolchain.file /path/to/sources}
  \begin{itemize}
    \item The {\em toolchain file} describes your toolchain, and can
      be generated by your embedded Linux build system. Makes the
      cross-compilation process very easy.
  \end{itemize}
\item Compilation\\{\tt make}
\item Installation\\{\tt make DESTDIR=/path/to/rootfs install}
\end{itemize}

\end{frame}

\begin{frame}{Qt and embedded Linux build systems}

  {\em Qt} is packaged is many embedded Linux build systems, which
  makes it quite easy to use and integrate in your system:

\begin{itemize}

  \item {\bf Buildroot}, my favorite. Possible to select at
    configuration time which {\em Qt} components should be built. Also
    generates a {\em CMake} toolchain file.

  \item {\bf OpenEmbedded/Yocto}. Always builds a full-blown Qt, but
    possible to install only some parts to the target root filesystem.

  \item {\bf OpenBricks}, same thing.

  \item {\bf PTXDist}, also allows to customize the {\em Qt}
    configuration to select only the required modules.

\end{itemize}

\end{frame}

\begin{frame}{Documentation}

Excellent documentation: both reference documentation and tutorials,
at \url{http://doc.qt.nokia.com/}.

\begin{center}
\includegraphics[width=\textwidth]{qt-doc-screenshot.png}
\end{center}

\end{frame}

\begin{frame}{Books}

  \begin{columns}[c]
    \column{0.5\textwidth}
    \begin{center}
    \includegraphics[height=0.4\textheight]{book1.jpg}\\
    \includegraphics[height=0.4\textheight]{book2.jpg}
    \end{center}
    \column{0.5\textwidth}
    \begin{center}
    \includegraphics[height=0.4\textheight]{book3.jpg}\\
    \includegraphics[height=0.4\textheight]{book4.jpg}
    \end{center}
   \end{columns}

\end{frame}

\begin{frame}{Issues encountered}

The development of our application went very smoothly, and {\em Qt}
allowed to focus on the application itself rather than little
``details''. Our only issues were:

\begin{itemize}

\item The fully {\em asynchronous} paradigm of signal/slot makes it a
  little bit involved to write purely sequential segments of code. Our
  case was managing the GPRS modem, which involves sending multiple
  {\tt AT} commands in sequence. We had to write a moderately
  elaborate state machine for something that is in the end quite
  simple.

\item The single-threaded architecture is very sensitive to
  delays/timeouts. By default, the {\em QExtSerialPort} configures the
  serial ports to wait 500ms before giving up reading ({\em VTIME}
  termios). This caused our application to loose events from {\em
    LinuxInput} devices.

\end{itemize}

\end{frame}

\begin{frame}{Conclusion}

{\em Qt} really met all its promises:

\begin{itemize}

  \item It was easy to learn, even for a very moderately-skilled C++
    programmer (me !)

  \item It allowed to develop the application very quickly by
    focusing on the application logic rather than ``low-level''
    details (XML parsing, HTTP requests, event management, etc.)

  \item Ease of programming very close to Python. You code something,
    and it just works.

  \item The skills have already been re-used for the development of
    another Qt application, this time a graphical demo application for
    a customer.

\end{itemize}

{\bf I would therefore strongly recommend considering the use of {\em
    Qt} amongst the possible frameworks for your applications, even
  non-graphical ones.}

\end{frame}

\begin{frame}
  \begin{center}
  \Huge
  Questions?\\
  \vspace{1.5cm}
  \huge
  Thomas Petazzoni\\
  \large
  \vspace{0.5cm}
  \code{thomas.petazzoni@bootlin.com}
  \vspace{1.5cm}\\
  \scriptsize
  Slides under CC-BY-SA 3.0.
  \end{center}

\end{frame}

\end{document}
