このページでは

シリアルターミナル

QSerialPort のさまざまな機能の使用方法を紹介します。

「Terminal」では、 Qt Serial Port。

Qt Serial Portターミナル

この例では、設定やI/Oの実装など、QSerialPort クラスの主な機能について説明します。また、システムで使用可能なシリアルポートに関する情報を表示するために、QSerialPortInfo クラスが呼び出されます。

QSerialPort は、2つの一般的なプログラミング手法をサポートしています:

  • 非同期(ノンブロッキング)方式。操作はスケジュールされ、制御がQtのイベントループに戻った際に実行されます。 QSerialPort は、操作が完了するとシグナルを発行します。例えば、QSerialPort::write()は即座に返ります。データがシリアルポートに送信されると、QSerialPort はbytesWritten()を発行します。
  • 同期(ブロッキング)方式。非GUIおよびマルチスレッドアプリケーションでは、waitFor...() 関数(例:QSerialPort::waitForReadyRead())を呼び出すことで、操作が完了するまで呼び出し元のスレッドを一時停止させることができます。

この例では、非同期的なアプローチを示しています。「Blocking Receiver」の例では、同期的なアプローチが説明されています。

この例には、いくつかのGUIウィジェットが含まれています:

  • MainWindow (terminal/mainwindow.cpp) - QMainWindowを継承しており、設定やI/O処理などを含むシリアルポートプログラミングのすべての動作ロジックを格納するメインアプリケーションウィンドウです。
  • Console (terminal/console.cpp) - メインウィンドウの中核となるウィジェットで、送受信されたデータを表示します。このウィジェットは QPlainTextEdit クラスを継承しています。
  • SettingsDialog (terminal/settingsdialog.cpp) - シリアルポートの設定を行うほか、利用可能なシリアルポートとその情報を表示するためのダイアログです。

シリアルポートは、MainWindow のコンストラクタ内でインスタンス化されます。メインウィジェットが親として渡されるため、Qtの親子メカニズムに従ってオブジェクトの削除が自動的に行われます:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    m_ui(new Ui::MainWindow),
    m_serial(new QSerialPort(this))
{
    ...

この例では、QSerialPort の以下のシグナルについて説明しています:

  • readyRead() - 新しいデータが受信され、利用可能になったことを示します
  • bytesWritten() - すべてのデータが正常に書き込まれたことを確認するために使用される
    ...
    connect(m_serial, &QSerialPort::readyRead, this, &MainWindow::readData);
    connect(m_serial, &QSerialPort::bytesWritten, this, &MainWindow::handleBytesWritten);
    ...
}

「Connect」ボタンをクリックすると、openSerialPort() のスロットが呼び出されます:

void MainWindow::openSerialPort()
{
    const SettingsDialog::Settings p = m_settings->settings();
    m_serial->setPortName(p.name);
    m_serial->setBaudRate(p.baudRate);
    m_serial->setDataBits(p.dataBits);
    m_serial->setParity(p.parity);
    m_serial->setStopBits(p.stopBits);
    m_serial->setFlowControl(p.flowControl);
    if (m_serial->open(QIODevice::ReadWrite)) {
        m_console->setEnabled(true);
        m_console->setLocalEchoEnabled(p.localEchoEnabled);
        m_ui->actionConnect->setEnabled(false);
        m_ui->actionDisconnect->setEnabled(true);
        m_ui->actionConfigure->setEnabled(false);
        showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
                          .arg(p.name, p.stringBaudRate, p.stringDataBits,
                               p.stringParity, p.stringStopBits, p.stringFlowControl));
    } else {
        QMessageBox::critical(this, tr("Error"), m_serial->errorString());

        showStatusMessage(tr("Open error"));
    }
}

このスロットでは、SettingsDialog から設定を読み取り、それに応じてシリアルポートのオープンと初期化を試みます。成功した場合、ステータスバーに指定された設定でポートのオープンに成功したというメッセージが表示されます。失敗した場合は、適切なエラーコードとメッセージを含むメッセージボックスが表示されます。 serialPortSettingsが一度も呼び出されたことがない場合、ターミナルはデフォルト設定(9600 8N1)でポートを開こうとします。

[切断] ボタンをクリックすると、closeSerialPort() スロットが呼び出されます:

void MainWindow::closeSerialPort()
{
    if (m_serial->isOpen())
        m_serial->close();
    m_console->setEnabled(false);
    m_ui->actionConnect->setEnabled(true);
    m_ui->actionDisconnect->setEnabled(false);
    m_ui->actionConfigure->setEnabled(true);
    showStatusMessage(tr("Disconnected"));
}

この場合、シリアルポートの閉じ処理によって処理されます。

[Configure] ボタンをクリックすると、SettingsDialog ウィジェットに属する `show() ` スロットが呼び出されます。

このメソッド(terminal/settingsdialog.cpp )は、SettingsDialog を表示します。このウィンドウでは、ユーザーは目的のシリアルポートを選択し、選択したポートに関する情報を確認し、そのシリアルポートのパラメータを設定することができます。

データの書き込み

コンソールに文字を入力すると、writeData() スロットが呼び出されます:

void MainWindow::writeData(const QByteArray &data)
{
    const qint64 written = m_serial->write(data);
    if (written == data.size()) {
        m_bytesToWrite += written;
        m_timer->start(kWriteTimeout);
    } else {
        const QString error = tr("Failed to write all data to port %1.\n"
                                 "Error: %2").arg(m_serial->portName(),
                                                  m_serial->errorString());
        showWriteError(error);
    }
}

このスロットは、指定されたConsoleウィジェットに入力された文字をシリアルポートに送信します(terminal/console.cpp を参照)。また、書き込みが実際に成功したかどうかを追跡するためのタイマーも開始します。すべてのバイトが実際に書き込まれたことを確認するために、bytesWritten()シグナルを使用します。これはMainWindow::handleBytesWritten() スロットに接続されています:

void MainWindow::handleBytesWritten(qint64 bytes)
{
    m_bytesToWrite -= bytes;
    if (m_bytesToWrite == 0)
        m_timer->stop();
}
データの読み取り

シリアルポートが新しいデータを受信すると、readyRead() シグナルが発信され、そのシグナルはMainWindow::readData() スロットに接続されています:

void MainWindow::readData()
{
    const QByteArray data = m_serial->readAll();
    m_console->putData(data);
}

このスロットは、シリアルポートからデータを読み取り、それをConsoleウィジェットに表示します。

例の動作

以下の手順でサンプルを実行できます:

code.qt.io のサンプルプロジェクト

「ブロッキング・レシーバー」も参照してください 。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.