├── Page1.qml ├── Page1Form.ui.qml ├── QMLSerialTerminal.pro ├── README.md ├── main.cpp ├── main.qml ├── qml.qrc ├── qtquickcontrols2.conf ├── serialterminal.cpp └── serialterminal.h /Page1.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.7 2 | 3 | Page1Form { 4 | 5 | Connections { 6 | 7 | target: serialTerminal 8 | 9 | onGetData: { 10 | 11 | terminal.append("<"+data); 12 | } 13 | 14 | } 15 | 16 | sendBtn.onClicked: { 17 | 18 | terminal.append(">"+dataToSend.text) 19 | serialTerminal.writeToSerialPortSlot(dataToSend.text+"\r\n") 20 | } 21 | 22 | 23 | connectBtn.onClicked: { 24 | 25 | if (serialTerminal.getConnectionStatusSlot() === false){ 26 | serialTerminal.openSerialPortSlot(serialPorts.currentText,serialPorts.currentText) 27 | connectBtn.text = "Disconnect" 28 | }else { 29 | 30 | serialTerminal.closeSerialPortSlot(); 31 | connectBtn.text = "Connect" 32 | } 33 | 34 | } 35 | 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Page1Form.ui.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.7 2 | import QtQuick.Controls 2.0 3 | import QtQuick.Layouts 1.0 4 | 5 | Item { 6 | 7 | property alias sendBtn: sendBtn 8 | property alias terminal: terminal 9 | property alias dataToSend: dataToSend 10 | property alias connectBtn: connectBtn 11 | 12 | 13 | Row { 14 | 15 | spacing: 40 16 | 17 | Column { 18 | 19 | y: 40 20 | 21 | 22 | Flickable { 23 | 24 | clip: true 25 | 26 | width: 500 27 | height: 100 28 | 29 | 30 | 31 | 32 | TextArea.flickable: TextArea { 33 | 34 | id: terminal 35 | wrapMode: TextArea.Wrap 36 | 37 | placeholderText: "Waiting..." 38 | width: 500 39 | height: 100 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | } 50 | 51 | 52 | 53 | 54 | } 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | TextField { 70 | 71 | id: dataToSend 72 | placeholderText: "Data to send..." 73 | width: 500 74 | 75 | } 76 | 77 | Button { 78 | 79 | id: sendBtn 80 | text: qsTr("Send") 81 | anchors.top: connectBtn.anchors.top 82 | 83 | } 84 | 85 | 86 | 87 | 88 | } 89 | 90 | Column { 91 | 92 | y: 40 93 | 94 | Label{ 95 | 96 | text: qsTr("Serial port: ") 97 | } 98 | 99 | ComboBox { 100 | 101 | id: serialPorts 102 | width: 100 103 | model: portsNameModel 104 | 105 | } 106 | 107 | Label { 108 | 109 | text: qsTr("Baud: ") 110 | } 111 | 112 | ComboBox { 113 | 114 | id: baudRate 115 | width: 100 116 | model: baudsModel 117 | 118 | } 119 | 120 | Button { 121 | 122 | id: connectBtn 123 | text: qsTr("Connect") 124 | 125 | } 126 | 127 | 128 | 129 | 130 | } 131 | 132 | 133 | 134 | } 135 | 136 | 137 | } 138 | -------------------------------------------------------------------------------- /QMLSerialTerminal.pro: -------------------------------------------------------------------------------- 1 | QT += qml quick 2 | 3 | CONFIG += c++11 4 | 5 | SOURCES += main.cpp 6 | 7 | RESOURCES += qml.qrc 8 | 9 | # Additional import path used to resolve QML modules in Qt Creator's code model 10 | QML_IMPORT_PATH = 11 | 12 | # Additional import path used to resolve QML modules just for Qt Quick Designer 13 | QML_DESIGNER_IMPORT_PATH = 14 | 15 | # The following define makes your compiler emit warnings if you use 16 | # any feature of Qt which as been marked deprecated (the exact warnings 17 | # depend on your compiler). Please consult the documentation of the 18 | # deprecated API in order to know how to port your code away from it. 19 | DEFINES += QT_DEPRECATED_WARNINGS 20 | 21 | # You can also make your code fail to compile if you use deprecated APIs. 22 | # In order to do so, uncomment the following line. 23 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 24 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 25 | 26 | # Default rules for deployment. 27 | qnx: target.path = /tmp/$${TARGET}/bin 28 | else: unix:!android: target.path = /opt/$${TARGET}/bin 29 | !isEmpty(target.path): INSTALLS += target 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple-Serial-Terminal 2 | Serial Terminal developed in C++/Qt and QML 3 | ![qmlserialterminalscreenshot](https://user-images.githubusercontent.com/23119112/31053543-f0b1afc4-a69f-11e7-9560-dbe27875cc1b.png) 4 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "serialterminal.h" 6 | #include 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 11 | QGuiApplication app(argc, argv); 12 | 13 | QSerialPortInfo serialPortInfo; 14 | QList ports = serialPortInfo.availablePorts(); 15 | QList bauds = serialPortInfo.standardBaudRates(); 16 | QStringList portsName; 17 | QStringList baudsStr; 18 | 19 | 20 | foreach (QSerialPortInfo port, ports) { 21 | 22 | portsName.append(port.portName()); 23 | 24 | } 25 | 26 | foreach (qint32 baud, bauds) { 27 | 28 | baudsStr.append(QString::number(baud)); 29 | 30 | } 31 | 32 | 33 | 34 | QQmlApplicationEngine engine; 35 | QQmlContext *context = engine.rootContext(); 36 | SerialTerminal serialTerminal; 37 | context->setContextProperty("serialTerminal",&serialTerminal); 38 | context->setContextProperty("portsNameModel",QVariant::fromValue(portsName)); 39 | context->setContextProperty("baudsModel",QVariant::fromValue(baudsStr)); 40 | 41 | engine.load(QUrl(QLatin1String("qrc:/main.qml"))); 42 | 43 | return app.exec(); 44 | } 45 | -------------------------------------------------------------------------------- /main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.7 2 | import QtQuick.Controls 2.0 3 | import QtQuick.Layouts 1.0 4 | 5 | ApplicationWindow { 6 | visible: true 7 | width: 720 8 | height: 480 9 | maximumHeight: 480 10 | maximumWidth: 720 11 | minimumWidth: 720 12 | minimumHeight: 480 13 | 14 | title: qsTr("Serial Terminal") 15 | 16 | 17 | 18 | 19 | 20 | Page1 { 21 | 22 | 23 | } 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main.qml 4 | Page1.qml 5 | Page1Form.ui.qml 6 | qtquickcontrols2.conf 7 | 8 | 9 | -------------------------------------------------------------------------------- /qtquickcontrols2.conf: -------------------------------------------------------------------------------- 1 | ; This file can be edited to change the style of the application 2 | ; See Styling Qt Quick Controls 2 in the documentation for details: 3 | ; http://doc.qt.io/qt-5/qtquickcontrols2-styles.html 4 | 5 | [Controls] 6 | Style=Material 7 | 8 | [Universal] 9 | Theme=Dark 10 | ;Accent=Steel 11 | 12 | [Material] 13 | Theme=Dark 14 | ;Accent=BlueGrey 15 | ;Primary=BlueGray 16 | -------------------------------------------------------------------------------- /serialterminal.cpp: -------------------------------------------------------------------------------- 1 | #include "serialterminal.h" 2 | #include 3 | 4 | SerialTerminal::SerialTerminal() 5 | { 6 | serialPort = new QSerialPort(this); 7 | } 8 | 9 | void SerialTerminal::openSerialPort(QString comName, int baud){ 10 | 11 | serialPort->setPortName(comName); 12 | serialPort->setBaudRate(baud); 13 | serialPort->setBaudRate(baud); 14 | serialPort->setFlowControl(QSerialPort::NoFlowControl); 15 | serialPort->setDataBits(QSerialPort::Data8); 16 | serialPort->setStopBits(QSerialPort::OneStop); 17 | serialPort->open(QIODevice::ReadWrite); 18 | connect(serialPort,SIGNAL(readyRead()),this,SLOT(readFromSerialPort())); 19 | 20 | 21 | 22 | 23 | } 24 | 25 | void SerialTerminal::closeSerialPort(){ 26 | 27 | serialPort->close(); 28 | 29 | } 30 | 31 | bool SerialTerminal::getConnectionStatus(){ 32 | 33 | return serialPort->isOpen(); 34 | 35 | } 36 | 37 | 38 | 39 | void SerialTerminal::writeToSerialPort(QString message){ 40 | 41 | const QByteArray &messageArray = message.toLocal8Bit(); 42 | serialPort->write(messageArray); 43 | } 44 | 45 | void SerialTerminal::openSerialPortSlot(QString comName, int baud){ 46 | 47 | this->openSerialPort(comName,baud); 48 | } 49 | 50 | void SerialTerminal::writeToSerialPortSlot(QString message){ 51 | 52 | this->writeToSerialPort(message); 53 | } 54 | 55 | void SerialTerminal::closeSerialPortSlot(){ 56 | 57 | this->closeSerialPort(); 58 | } 59 | 60 | bool SerialTerminal::getConnectionStatusSlot(){ 61 | 62 | return this->getConnectionStatus(); 63 | } 64 | 65 | void SerialTerminal::readFromSerialPort(){ 66 | 67 | if (serialPort->canReadLine()){ 68 | 69 | QString data = QString::fromLatin1(serialPort->readAll()); 70 | emit getData(data); 71 | } 72 | 73 | } 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /serialterminal.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALTERMINAL_H 2 | #define SERIALTERMINAL_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | 10 | class SerialTerminal : public QObject 11 | { 12 | Q_OBJECT 13 | public: 14 | SerialTerminal(); 15 | void openSerialPort(QString comName, int baud); 16 | void writeToSerialPort(QString message); 17 | bool getConnectionStatus(); 18 | void closeSerialPort(); 19 | 20 | public slots: 21 | 22 | void openSerialPortSlot(QString comName, int baud); 23 | void writeToSerialPortSlot(QString message); 24 | void readFromSerialPort(); 25 | bool getConnectionStatusSlot(); 26 | void closeSerialPortSlot(); 27 | 28 | 29 | 30 | private: 31 | 32 | QSerialPort *serialPort; 33 | 34 | 35 | 36 | signals: 37 | 38 | QString getData(QString data); 39 | 40 | 41 | 42 | }; 43 | 44 | #endif // SERIALTERMINAL_H 45 | --------------------------------------------------------------------------------