車両
Qt gRPC™ クライアントとC++のgRPC サーバー間の2つのスレッド接続を管理します。
この例では、gRPC サーバーから送信されたデータを表示する車両のダッシュボードをシミュレートしています。

このサンプルコードには、以下のコンポーネントが含まれています:
vehicle_clientメッセージおよびサービスのQtコードを生成するために、CMake関数qt_add_protobuf() およびqt_add_grpc()を使用するQt XMLgRPC クライアントアプリケーション。vehicle_serverサーバーコードの生成および単純なサーバーロジックの実装のために、C++gRPC プラグインを呼び出すアプリケーション。
注: C++gRPC プラグインがインストールされている必要があります 。詳細はこちらをご覧ください:モジュールの前提条件
どちらのコンポーネントも、vehicleservice.proto およびnavigationservice.proto ファイルに記述された protobuf スキーマから生成されたメッセージを使用します。
車両サービス:
message SpeedMsg {
int32 speed = 1;
}
message RpmMsg {
int32 rpm = 1;
}
message AutonomyMsg {
int32 autonomy = 1;
}
service VehicleService {
rpc getSpeedStream(google.protobuf.Empty) returns (stream SpeedMsg) {}
rpc getRpmStream(google.protobuf.Empty) returns (stream RpmMsg) {}
rpc getAutonomy(google.protobuf.Empty) returns (AutonomyMsg) {}
}ナビゲーションサービス:
enum DirectionEnum {
RIGHT = 0;
LEFT = 1;
STRAIGHT = 2;
BACKWARD = 3;
}
message NavigationMsg {
int32 totalDistance = 1;
int32 traveledDistance = 2;
DirectionEnum direction = 3;
string street = 4;
}
service NavigationService {
rpc getNavigationStream(google.protobuf.Empty) returns (stream NavigationMsg) {}
}VehicleManager のC++シングルトンは、2つのQThread インスタンスを使用して、サーバーと並行して通信を行います。各スレッドは、異なるgRPC 接続タイプを持っています。この例では、2つのタイプがあります:
- サーバーストリーミングRPC。例えば、車両スレッドの速度ストリームなどです。ここでは、QGrpcServerStream::messageReceived とQGrpcOperation::finished
Empty speedRequest; m_streamSpeed= m_client->getSpeedStream(speedRequest); connect(m_streamSpeed.get(), &QGrpcServerStream::messageReceived, this, [this]() { if(const autospeedResponse= m_streamSpeed->read<SpeedMsg>()) { emitspeedChanged(speedResponse->speed()); } }); connect( m_streamSpeed.get(), &QGrpcServerStream::finished, this, [this](constQGrpcStatus&status) { if(!status.isOk()) { autoerror=QString("速度 %1 (%2) の取得中にストリームエラーが発生しました") .arg(status.message()) .arg(QVariant::fromValue(status.code()).toString()); emitconnectionError(error); qWarning() << error; return; } }, Qt::SingleShotConnection); - 単項RPCRPCの
getAutonomy操作は単項RPCです。単一の応答を返します。QGrpcOperation::finished シグナルにのみ接続されています。autonomyRequest = empty; std::unique_ptr<QGrpcCallReply>autonomyReply= m_client->getAutonomy(autonomyRequest); const auto *autonomyReplyPtr =autonomyReply.get(); connect( autonomyReplyPtr, &QGrpcCallReply::finished, this, [this,autonomyReply=std::move(autonomyReply)](constQGrpcStatus&status) { if(!status.isOk()) { autoerror=QString("自律性 %1 (%2) の取得中にエラーが発生しました") .arg(status.message()) .arg(QVariant::fromValue(status.code()).toString()); emitconnectionError(error); qWarning() << error; return; } if(const autoautonomyMsg= autonomyReply->read<AutonomyMsg>()) { emitautonomyChanged(autonomyMsg->autonomy()); } }, Qt::SingleShotConnection);
クライアントのメインウィンドウのインターフェースは、Main.qml ファイルで定義されています。ここでは、VehicleManager というC++シングルトンのシグナルをカスタムスロットに接続するために、QMLのConnections 型が使用されています:
Connections {
target: VehicleManager
// This slot will be executed when the VehicleManager::totalDistanceChanged
// signal is emitted
function onTotalDistanceChanged(distance: int): void {
root.totalDistance = distance;
}
function onSpeedChanged(speed: int): void {
root.speed = speed;
}
function onRpmChanged(rpm: int): void {
root.rpm = rpm;
}
function onTraveledDistanceChanged(distance: int): void {
root.traveledDistance = distance;
}
function onDirectionChanged(direction: int): void {
if (direction == VehicleManager.RIGHT) {
root.directionImageSource = "qrc:/direction_right.svg";
} else if (direction == VehicleManager.LEFT) {
root.directionImageSource = "qrc:/direction_left.svg";
} else if (direction == VehicleManager.STRAIGHT) {
root.directionImageSource = "qrc:/direction_straight.svg";
} else {
root.directionImageSource = "";
}
}応答を受信すると、クライアントウィンドウは受信したデータに基づいて UI を更新します。このようにして、メッセージは異なるスレッドで受信され、シグナルのおかげでスレッドセーフな方法でクライアント UI に送信されます。
© 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.