summaryrefslogtreecommitdiffstats
path: root/examples/serialport/doc
diff options
context:
space:
mode:
authorKai Koehne <kai.koehne@digia.com>2013-04-30 14:46:08 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-03 17:01:47 +0200
commit494c616951d41f2f394a7157f8970e14096f41b4 (patch)
tree9e42e9970b4b28809d97c0de94acc9fa7a81c54e /examples/serialport/doc
parentbcdeb589dd9d3b0ff7270d380d043b1882eefdc0 (diff)
Fix examples directory layout
Move examples into a dedicated 'serialport' directory. This is in line with what the other modules do, and makes sure that the examples show up in a sensible place even for the 'combined' source packages. Task-number: QTBUG-30912 Change-Id: Iefa2b634df3d2eb34f655b34f6fb24a224b78869 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Laszlo Papp <lpapp@kde.org> Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Diffstat (limited to 'examples/serialport/doc')
-rw-r--r--examples/serialport/doc/blockingmaster.qdoc162
-rw-r--r--examples/serialport/doc/blockingslave.qdoc164
-rw-r--r--examples/serialport/doc/cenumerator.qdoc45
-rw-r--r--examples/serialport/doc/enumerator.qdoc43
-rw-r--r--examples/serialport/doc/terminal.qdoc144
5 files changed, 558 insertions, 0 deletions
diff --git a/examples/serialport/doc/blockingmaster.qdoc b/examples/serialport/doc/blockingmaster.qdoc
new file mode 100644
index 00000000..40ac0702
--- /dev/null
+++ b/examples/serialport/doc/blockingmaster.qdoc
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 - 2012 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example blockingmaster
+ \title Blocking Master Example
+ \ingroup qtserialport-examples
+
+ The Blocking Master example shows how to create a application for a
+ serial interface using QSerialPort's synchronous API in a non-GUI thread.
+
+ \image blockingmaster-example.png Screenshot of the Blocking Master example
+
+ QSerialPort supports two general programming approaches:
+
+ \list
+
+ \li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
+ and performed when the control returns to Qt's event loop. QSerialPort emits
+ a signal when the operation is finished. For example, QSerialPort::write()
+ returns immediately. When the data is sent to the serial port, QSerialPort
+ emits \l{QSerialPort::bytesWritten()}{bytesWritten()}.
+
+ \li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
+ applications, the \c waitFor...() functions can be called (i.e.
+ QSerialPort::waitReadyRead()) to suspend the calling thread until the
+ operation has completed.
+
+ \endlist
+
+ In this example, the synchronous approach is demonstrated. The
+ \l{terminal}{Simple Terminal} example illustrates the
+ asynchronous approach.
+
+ The purpose of this example is to demonstrate a pattern that you can use
+ to simplify your serial programming code, without losing responsiveness
+ in your user interface. Use of Qt's blocking serial programming API often
+ leads to simpler code, but because of its blocking behavior, it should only
+ be used in non-GUI threads to prevent the user interface from freezing.
+ But contrary to what many think, using threads with QThread does not
+ necessarily add unmanagable complexity to your application.
+
+ This application is a Master, that demonstrate the work paired with Slave
+ application \l{blockingslave}{Blocking Slave Example}.
+
+ The Master application is initiate the transfer request via serial port to
+ the Slave application and wait for a response from it.
+
+ We will start with the MasterThread class, which handles the serial
+ programming code.
+
+ \snippet blockingmaster/masterthread.h 0
+
+ MasterThread is a QThread subclass that provides an API for scheduling
+ requests to Slave, and it has signals for delivering responses and reporting
+ errors. You can call transaction() to startup new master transaction with
+ desired request data and other parameters, and the result is delivered by
+ the response() signal. If any error occurs, the error() or timeout() signals
+ is emitted.
+
+ It's important to notice that transaction() is called from the main, GUI
+ thread, but the request data and other parameters will be accessed from
+ MasterThread's thread. Because we will be reading and writing MasterThread's
+ data members from different threads concurrently, we use QMutex to
+ synchronize access.
+
+ \snippet blockingmaster/masterthread.cpp 2
+
+ The transaction() function stores the serial port name, timeout and request
+ data, and we lock the mutex with QMutexLocker to protect this data. We then
+ start the thread, unless it is already running. We will come back to the
+ QWaitCondition::wakeOne() call later.
+
+ \snippet blockingmaster/masterthread.cpp 4
+ \snippet blockingmaster/masterthread.cpp 5
+
+ In the run() function, we start by acquiring the mutex lock, fetching the
+ serial port name, timeout and request data from the member data, and then
+ releasing the lock again. The case that we are protecting ourselves against
+ is that \c transaction() could be called at the same time as we are fetching
+ this data. QString is \l reentrant but \e not \l{thread-safe}, and we must
+ also avoid the unlikely risk of reading the serial port name from one request,
+ and timeout or request data of another. And as you might have guessed,
+ MasterThread can only handle one request at a time.
+
+ The QSerialPort object we construct on stack into run() function before loop
+ enter:
+
+ \snippet blockingmaster/masterthread.cpp 6
+
+ This allows us once to create an object, while running loop, and also means
+ that all the methods of the object will be executed in the context of the
+ run() thread.
+
+ In the loop, we check for changed or not the name of serial port for the
+ current transaction. And if the name is changed then re-open and re-configure
+ the serial port.
+
+ \snippet blockingmaster/masterthread.cpp 7
+
+ The loop will continue creating request data, write to serial port and wait
+ until all data is transferred.
+
+ \snippet blockingmaster/masterthread.cpp 8
+
+ \warning The method waitForBytesWritten() should be used after each write()
+ call for the blocking approach, because it processes all the I/O routines
+ instead of Qt event-loop.
+
+ The timeout() signal is emitted if error occurs when transferring data.
+
+ \snippet blockingmaster/masterthread.cpp 9
+
+ After a successful request, we start wait until response and try read it.
+
+ \snippet blockingmaster/masterthread.cpp 10
+
+ \warning The method waitForReadyRead() should be used before each read()
+ call for the blocking approach, because it processes all the I/O routines
+ instead of Qt event-loop.
+
+ The timeout() signal is emitted if error occurs when receiving data.
+
+ \snippet blockingmaster/masterthread.cpp 11
+
+ After a successful transaction is emitted response() signal containing the
+ data received from the Slave application:
+
+ \snippet blockingmaster/masterthread.cpp 12
+
+ Next, the thread goes to sleep until the next transaction is appear. On
+ waking, the thread re-reads the new data of members and run loop from the
+ beginning.
+
+ \snippet blockingmaster/masterthread.cpp 13
+
+ \sa {Simple Terminal Example}, {Blocking Slave Example}
+*/
diff --git a/examples/serialport/doc/blockingslave.qdoc b/examples/serialport/doc/blockingslave.qdoc
new file mode 100644
index 00000000..4b835d98
--- /dev/null
+++ b/examples/serialport/doc/blockingslave.qdoc
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 - 2012 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example blockingslave
+ \title Blocking Slave Example
+ \ingroup qtserialport-examples
+
+ The Blocking Slave example shows how to create a application for a
+ serial interface using QSerialPort's synchronous API in a non-GUI thread.
+
+ \image blockingslave-example.png Screenshot of the Blocking Slave example
+
+ QSerialPort supports two general programming approaches:
+
+ \list
+
+ \li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
+ and performed when the control returns to Qt's event loop. QSerialPort emits
+ a signal when the operation is finished. For example, QSerialPort::write()
+ returns immediately. When the data is sent to the serial port, QSerialPort
+ emits \l{QSerialPort::bytesWritten()}{bytesWritten()}.
+
+ \li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
+ applications, the \c waitFor...() functions can be called (i.e.
+ QSerialPort::waitReadyRead()) to suspend the calling thread until the
+ operation has completed.
+
+ \endlist
+
+ In this example, the synchronous approach is demonstrated. The
+ \l{slave}{Slave Example} example illustrates the asynchronous approach.
+
+ The purpose of this example is to demonstrate a pattern that you can use
+ to simplify your serial programming code, without losing responsiveness
+ in your user interface. Use of Qt's blocking serial programming API often
+ leads to simpler code, but because of its blocking behavior, it should only
+ be used in non-GUI threads to prevent the user interface from freezing.
+ But contrary to what many think, using threads with QThread does not
+ necessarily add unmanagable complexity to your application.
+
+ This application is a Slave, that demonstrate the work paired with Master
+ application \l{blockingmaster}{Blocking Master Example}.
+
+ The Slave application is receives the request via serial port from
+ the Master application and send a response to it.
+
+ We will start with the SlaveThread class, which handles the serial
+ programming code.
+
+ \snippet blockingslave/slavethread.h 0
+
+ SlaveThread is a QThread subclass that provides an API for receive requests
+ from Master, and it has signals for delivering responses and reporting
+ errors.
+
+ You should be call startSlave() to startup Slave application. This method
+ transfers to the SlaveThread desired parameters for configure and startup
+ the serial interface. When SlaveThread received from Master any request then
+ emitted the request() signal. If any error occurs, the error() or timeout()
+ signals is emitted.
+
+ It's important to notice that startSlave() is called from the main, GUI
+ thread, but the response data and other parameters will be accessed from
+ SlaveThread's thread. Because we will be reading and writing SlaveThread's
+ data members from different threads concurrently, we use QMutex to
+ synchronize access.
+
+ \snippet blockingslave/slavethread.cpp 2
+
+ The startSlave() function stores the serial port name, timeout and response
+ data, and we lock the mutex with QMutexLocker to protect this data. We then
+ start the thread, unless it is already running. We will come back to the
+ QWaitCondition::wakeOne() call later.
+
+ \snippet blockingslave/slavethread.cpp 4
+ \snippet blockingslave/slavethread.cpp 5
+
+ In the run() function, we start by acquiring the mutex lock, fetching the
+ serial port name, timeout and response data from the member data, and then
+ releasing the lock again. The case that we are protecting ourselves against
+ is that \c startSlave() could be called at the same time as we are fetching
+ this data. QString is \l reentrant but \e not \l{thread-safe}, and we must
+ also avoid the unlikely risk of reading the serial port name from one startup,
+ call and timeout or response data of another. And as you might have guessed,
+ SlaveThread can only handle one startup at a time.
+
+ The QSerialPort object we construct on stack into run() function before loop
+ enter:
+
+ \snippet blockingslave/slavethread.cpp 6
+
+ This allows us once to create an object, while running loop, and also means
+ that all the methods of the object will be executed in the context of the
+ run() thread.
+
+ In the loop, we check for changed or not the name of serial port for the
+ current startup. And if the name is changed then re-open and re-configure
+ the serial port.
+
+ \snippet blockingslave/slavethread.cpp 7
+
+ The loop will continue wait for reading request data:
+
+ \snippet blockingslave/slavethread.cpp 8
+
+ \warning The method waitForReadyRead() should be used before each read()
+ call for the blocking approach, because it processes all the I/O routines
+ instead of Qt event-loop.
+
+ The timeout() signal is emitted if error occurs when reading data.
+
+ \snippet blockingslave/slavethread.cpp 9
+
+ After a successful read, we try send response and wait completion of the
+ transfer:
+
+ \snippet blockingslave/slavethread.cpp 10
+
+ \warning The method waitForBytesWritten() should be used after each write()
+ call for the blocking approach, because it processes all the I/O routines
+ instead of Qt event-loop.
+
+ The timeout() signal is emitted if error occurs when writing data.
+
+ \snippet blockingslave/slavethread.cpp 11
+
+ After a successful writing is emitted request() signal containing the
+ data received from the Master application:
+
+ \snippet blockingslave/slavethread.cpp 12
+
+ Next, the thread goes to re-reads the current parameters for serial interface,
+ because they can be updated when new startSlave() and run loop from the
+ beginning.
+
+ \snippet blockingslave/slavethread.cpp 13
+
+ \sa {Simple Terminal Example}, {Blocking Master Example}
+*/
diff --git a/examples/serialport/doc/cenumerator.qdoc b/examples/serialport/doc/cenumerator.qdoc
new file mode 100644
index 00000000..0766931a
--- /dev/null
+++ b/examples/serialport/doc/cenumerator.qdoc
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example cenumerator
+ \title Command Line Enumerator Example
+ \ingroup qtserialport-examples
+
+ The Command Line Enumerator example shows how to use the class
+ QSerialPortInfo for getting information about serial devices that are present
+ in the system.
+
+ \image cenumerator-example.png Screenshot of the Command Line Enumerator
+ example
+
+ This command line example displays information about serial ports in a
+ console, provided by the class QSerialPortInfo.
+
+ For getting information about the available ports, use the static method
+ \l{QSerialPortInfo::availablePorts()}{availablePorts()}.
+*/
diff --git a/examples/serialport/doc/enumerator.qdoc b/examples/serialport/doc/enumerator.qdoc
new file mode 100644
index 00000000..0847d8a8
--- /dev/null
+++ b/examples/serialport/doc/enumerator.qdoc
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 - 2012 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example enumerator
+ \title Enumerator Example
+ \ingroup qtserialport-examples
+
+ The Enumerator example shows how to use the class QSerialPortInfo for
+ getting information about serial devices that are present in the system.
+
+ \image enumerator-example.png Screenshot of the Enumerator example
+
+ This GUI example displays information about serial ports in a widget,
+ provided by the class QSerialPortInfo.
+
+ For getting information about the available ports, use the static method
+ \l{QSerialPortInfo::availablePorts()}{availablePorts()}.
+*/
diff --git a/examples/serialport/doc/terminal.qdoc b/examples/serialport/doc/terminal.qdoc
new file mode 100644
index 00000000..b432390b
--- /dev/null
+++ b/examples/serialport/doc/terminal.qdoc
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 - 2012 Denis Shienkov <denis.shienkov@gmail.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example terminal
+ \title Terminal Example
+ \ingroup qtserialport-examples
+
+ The Terminal example shows how to create a terminal for a simple serial
+ interface by using Qt Serial Port.
+
+ \image terminal-example.png Screenshot of the Terminal example
+
+ This example shows the main features of the QSerialPort class, like
+ configuration, I/O implementation and so forth. Also, the class
+ QSerialPortInfo is invoked to display information about the serial ports
+ available in the system.
+
+ QSerialPort supports two general programming approaches:
+
+ \list
+
+ \li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
+ and performed when the control returns to Qt's event loop. QSerialPort emits
+ a signal when the operation is finished. For example, QSerialPort::write()
+ returns immediately. When the data is sent to the serial port, QSerialPort
+ emits \l{QSerialPort::bytesWritten()}{bytesWritten()}.
+
+ \li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
+ applications, the \c waitFor...() functions can be called (i.e.
+ QSerialPort::waitReadyRead()) to suspend the calling thread until the
+ operation has completed.
+
+ \endlist
+
+ In this example, the asynchronous approach is demonstrated.
+
+ Our example contains some GUI widgets:
+
+ \list
+
+ \li \l{terminal/mainwindow.cpp}{MainWindow} - is the main application
+ window that contains all the working logic for the serial port programming,
+ including configuration, I/O processing and so forth, while inheriting the
+ QMainWindow.
+
+ \li \l{terminal/console.cpp}{Console} - is the central widget of the
+ main window, displaying the transmitted or received data. The widget is
+ derived from the QPlainTextEdit class.
+
+ \li \l{terminal/settingsdialog.cpp}{SettingsDialog} - is a dialog
+ for configuring the serial port, as well as for displaying the available
+ serial ports and information about them.
+
+ \endlist
+
+ The serial port is instantiated in the \l{terminal/mainwindow.cpp}{MainWindow}
+ constructor. The main widget is passed as the parent, so the object deletion
+ happens automatically according to the the parent and child mechanism in Qt:
+
+ \snippet terminal/mainwindow.cpp 0
+ \dots
+ \snippet terminal/mainwindow.cpp 1
+
+ The only QSerialPort signal invoked in this example is
+ QSerialPort::readyRead(), which shows that new data has been received and
+ hence available:
+
+ \dots
+ \snippet terminal/mainwindow.cpp 2
+ \dots
+ \snippet terminal/mainwindow.cpp 3
+
+ Clicking on the \b{Connect} button invokes the \c openSerialPort() slot:
+
+ \snippet terminal/mainwindow.cpp 4
+
+ In this slot, the settings are read from \l{terminal/settingsdialog.cpp}
+ {SettingsDialog} and an attempt is made to open and initialize the serial
+ port accordingly. If successful, the status bar displays a message that the
+ opening was successful with the given configuration; otherwise, a messagebox
+ is displayed with the appropriate error code and message. If the serial port
+ settings have never been called
+ \l{terminal/settingsdialog.cpp}{SettingsDialog}, then the terminal
+ attempts to open the port with the default settings: 9600 8N1.
+
+ Clicking on the \b{Disconnect} button invokes the \c closeSerialPort()
+ slot:
+
+ \snippet terminal/mainwindow.cpp 5
+
+ In this case, handled by the closure of the serial port.
+
+ Typing characters in the console invokes the \c writeData() slot:
+
+ \snippet terminal/mainwindow.cpp 6
+
+ This slot sends the characters typed in the given
+ \l{terminal/console.cpp}{Console} widget to the serial port.
+
+ When the serial port receives new data, the signal
+ \l{QTcpSocket::readyRead()}{readyRead()} is emitted, and that signal is
+ connected to the \c MainWindow::readData() slot:
+
+ \snippet terminal/mainwindow.cpp 7
+
+ This slot reads the data from the serial port and displays that in the
+ \l{terminal/console.cpp}{Console} widget.
+
+ Clicking on the \b{Configure} button invokes the \c show() slot which
+ belongs to the \l{terminal/settingsdialog.cpp}{SettingsDialog}
+ widget.
+
+ This method displays the \l{terminal/settingsdialog.cpp}{SettingsDialog}
+ in which the user can choose the desired serial port, see the information
+ about the selected port, and set the desired parameters of the given serial
+ port.
+
+ \sa {Blocking Simple Terminal Example}
+*/