Qt6/C++17 serial terminal with modular protocol parsing, real-time plotting (QCustomPlot), and a clean layered architecture. Built for embedded development, PCB debugging, and sensor data visualization.
- Multi-protocol support via pluggable strategies (ASCII, Hex, VOFA-Link, custom)
- Real-time plotting with QCustomPlot
- High-performance, zero-allocation line parser using QStringView
- Thread-safe serial I/O with connection state signals
- Dark Catppuccin-inspired UI theme
- Qt 6.x (tested with Qt 6.10.0)
- CMake 3.16+
- C++17 compiler (MinGW, MSVC, GCC, Clang)
- Open
CMakeLists.txtin Qt Creator. - Configure with your Qt kit.
- Build and run.
mkdir build && cd build
cmake .. -G "Ninja" -DCMAKE_PREFIX_PATH=/path/to/Qt/6.x.x/mingw_64
cmake --build .(Use -DCMAKE_PREFIX_PATH=/path/to/Qt/6.x.x/gcc_64 for GCC/Clang toolchains.)
- View menu toggles docks: Parser Config Panel and Serial Settings Panel (both closable/floatable).
- Parser Config:
- Choose delimiter (space/comma/tab/semicolon/custom).
- Select fields (0–15) to plot as channels.
- Optional ID filter: enable, set ID field index, and Accept ID.
- Strip labels when tokens look like
X:123. - X-axis source: timestamp, counter, or field.
- Presets: CSV/Space/Tab/Hall/Labeled.
- Test Parse shows success/error using the last received line.
- Terminal view supports raw/hex/parsed display and a send box with ASCII/hex auto-detect.
SerialManager -> ProtocolHandler -> LineParser -> DataBuffer -> Terminal/Plotter
- SerialManager: threaded QSerialPort wrapper emitting raw bytes and connection signals.
- ProtocolHandler + LineParser: strategy-based parsing, configurable at runtime.
- DataBuffer: ring buffer for parsed history.
- Widgets: Terminal, Plotter, Serial Settings, Parser Config.
- Derive from
BaseProtocol. - Implement
parse(),name(),description(), andreset(). - Register via
ProtocolHandler::registerProtocol().
Example:
class MyProtocol : public BaseProtocol {
Q_OBJECT
public:
void parse(const QByteArray &data) override {
// Parse data and emit dataParsed()
}
QString name() const override { return "My Protocol"; }
QString description() const override { return "Custom protocol"; }
void reset() override { /* Clear buffers */ }
};ComStudio/
├── src/
│ ├── core/ # SerialManager, ProtocolHandler, LineParser
│ ├── ui/ # MainWindow, Widgets
│ ├── models/ # DataBuffer
│ └── main.cpp
├── include/ # Headers
│ ├── core/
│ ├── ui/
│ └── models/
├── assets/
│ ├── styles/ # QSS stylesheets
│ └── icons/ # Application icons
├── third_party/
│ └── QCustomPlot/ # Plotting library
└── CMakeLists.txt
Uses QCustomPlot, licensed under GPL v3.
- Classes: PascalCase
- Methods: camelCase
- Member variables: m_variableName
- Prefer Doxygen comments
- Never block the UI thread
- …
- …
- …