Qt Remote Object(QtRO)实现进程间通信——遥控小车(二)

还是先看看运行效果:
Qt Remote Object(QtRO)实现进程间通信——遥控小车(二)_第1张图片
这次我们再Rep文件中使用枚举

class CommonInterface
{
    ENUM CarOperation {
        Accelerate,
        Decelerate,
        TurnLeft,
        TurnRight
    }
    SIGNAL(sigMessage(CarOperation operation))   //server下发消息给client
}

如果你用的Qt版本是5.9的话,这里可能会有问题,我用的是Qt5…14.1,这样写没有问题。
Qt5.9的朋友遇到问题不要紧张,看这里:QtRO rep中定义枚举类型要避免的坑

这次我们直接放代码:
1.客户端(小车)
car.h

#ifndef CAR_H
#define CAR_H

#include 
#include 

#include 
#include "rep_CommonInterface_replica.h"

class Car : public QGraphicsObject
{
    Q_OBJECT
public:
    Car();
    QRectF boundingRect() const;

public Q_SLOTS:
    void accelerate();
    void decelerate();
    void turnLeft();
    void turnRight();

    void onSigMessage(CommonInterfaceReplica::CarOperation operation);

Q_SIGNALS:
    void crashed();

protected:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
    void timerEvent(QTimerEvent *event);

private:
    void init();

private:
    QBrush color;
    qreal wheelsAngle; // used when applying rotation
    qreal speed; // delta movement along the body axis

    QRemoteObjectNode * m_pRemoteNode = nullptr;
    std::shared_ptr<CommonInterfaceReplica> m_pInterface = nullptr;
};

#endif // CAR_H

car.cpp

#include "car.h"
#include 
#include 

QRectF Car::boundingRect() const
{
    return QRectF(-35, -81, 70, 115);
}

Car::Car() : color(Qt::green), wheelsAngle(0), speed(0)
{
    startTimer(1000 / 33);
    setFlag(QGraphicsItem::ItemIsMovable, true);
    setFlag(QGraphicsItem::ItemIsFocusable, true);

    init();
}

void Car::accelerate()
{
    if (speed < 10)
        ++speed;
}

void Car::decelerate()
{
    if (speed > -10)
        --speed;
}

void Car::turnLeft()
{
    if (wheelsAngle > -30)
        wheelsAngle -= 5;
}

void Car::turnRight()
{
    if (wheelsAngle < 30)
        wheelsAngle += 5;
}

void Car::onSigMessage(CommonInterfaceReplica::CarOperation operation)
{
    qDebug() << "operation:" << operation;
    switch (operation) {
    case CommonInterfaceReplica::Accelerate:
        accelerate();
        break;

    case CommonInterfaceReplica::Decelerate:
        decelerate();
        break;

    case CommonInterfaceReplica::TurnLeft:
        turnLeft();
        break;

    case CommonInterfaceReplica::TurnRight:
        turnRight();
        break;
    }
}

void Car::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option)
    Q_UNUSED(widget)

    painter->setBrush(Qt::gray);
    painter->drawRect(-20, -58, 40, 2); // front axel
    painter->drawRect(-20, 7, 40, 2); // rear axel

    painter->setBrush(color);
    painter->drawRect(-25, -79, 50, 10); // front wing

    painter->drawEllipse(-25, -48, 50, 20); // side pods
    painter->drawRect(-25, -38, 50, 35); // side pods
    painter->drawRect(-5, 9, 10, 10); // back pod

    painter->drawEllipse(-10, -81, 20, 100); // main body

    painter->drawRect(-17, 19, 34, 15); // rear wing

    painter->setBrush(Qt::black);
    painter->drawPie(-5, -51, 10, 15, 0, 180 * 16);
    painter->drawRect(-5, -44, 10, 10); // cocpit

    painter->save();
    painter->translate(-20, -58);
    painter->rotate(wheelsAngle);
    painter->drawRect(-10, -7, 10, 15); // front left
    painter->restore();

    painter->save();
    painter->translate(20, -58);
    painter->rotate(wheelsAngle);
    painter->drawRect(0, -7, 10, 15); // front left
    painter->restore();

    painter->drawRect(-30, 0, 12, 17); // rear left
    painter->drawRect(19, 0, 12, 17);  // rear right
}

void Car::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event)

    const qreal axelDistance = 54;
    qreal wheelsAngleRads = qDegreesToRadians(wheelsAngle);
    qreal turnDistance = ::cos(wheelsAngleRads) * axelDistance * 2;
    qreal turnRateRads = wheelsAngleRads / turnDistance;  // rough estimate
    qreal turnRate = qRadiansToDegrees(turnRateRads);
    qreal rotation = speed * turnRate;

    setTransform(QTransform().rotate(rotation), true);
    setTransform(QTransform::fromTranslate(0, -speed), true);
    update();
}

void Car::init()
{
    m_pRemoteNode = new QRemoteObjectNode(this);
    bool isConnected = m_pRemoteNode->connectToNode(QUrl("local:interfaces"));
    qDebug() << "isConnected:" << isConnected;
    m_pInterface = std::shared_ptr<CommonInterfaceReplica>(m_pRemoteNode->acquire<CommonInterfaceReplica>());
    qDebug() << "waitForSource:" << m_pInterface->waitForSource(); //这里是阻塞的,待优化

    connect(m_pInterface.get(), &CommonInterfaceReplica::sigMessage, this, &Car::onSigMessage);
}

main.cpp

#include "car.h"
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QGraphicsScene scene;
    scene.setSceneRect(-500, -500, 1000, 1000);
    scene.setItemIndexMethod(QGraphicsScene::NoIndex);

    Car *car = new Car();
    scene.addItem(car);

    QGraphicsView view(&scene);
    view.setRenderHint(QPainter::Antialiasing);
    view.setBackgroundBrush(Qt::darkGray);
    view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Qt Remote Objects Controlled Car"));
    view.resize(400, 300);
    view.show();

    return app.exec();
}

pro文件

QT += widgets remoteobjects

HEADERS += car.h
SOURCES += car.cpp main.cpp

REPC_REPLICA += ../Reps/CommonInterface.rep

2.服务器端(控制端)
controller.pro

QT += widgets remoteobjects

FORMS += controller.ui
HEADERS += controller.h \
    commoninterface.h
SOURCES += main.cpp controller.cpp \
    commoninterface.cpp

REPC_SOURCE += ../Reps/CommonInterface.rep

commoninterface.h

#ifndef COMMONINTERFACE_H
#define COMMONINTERFACE_H

#include "rep_commoninterface_source.h"

class CommonInterface : public CommonInterfaceSource
{
    Q_OBJECT
public:
    explicit CommonInterface(QObject * parent = nullptr);

    void sendMsg(CommonInterfaceSource::CarOperation operation);
};

#endif // COMMONINTERFACE_H

commoninterface.cpp

#include "commoninterface.h"
#include 

CommonInterface::CommonInterface(QObject *parent):
    CommonInterfaceSource(parent)
{
}

/**
 * @brief CommonInterface::sendMsg
 * @param msg
 * 发送消息给客户端
 */
void CommonInterface::sendMsg(CommonInterfaceSource::CarOperation operation)
{
    emit sigMessage(operation);
}

controller.h

#ifndef CONTROLLER_H
#define CONTROLLER_H

#include "ui_controller.h"

#include "commoninterface.h"
#include 

class Controller : public QWidget
{
    Q_OBJECT

public:
    Controller(QWidget *parent = nullptr);

protected:
    void timerEvent(QTimerEvent *event);

private slots:
    void on_accelerate_clicked();
    void on_decelerate_clicked();
    void on_left_clicked();
    void on_right_clicked();

private:
    void init();

private:
    Ui::Controller ui;

    CommonInterface * m_pInterface = nullptr;
    QRemoteObjectHost * m_pHost = nullptr;
};

#endif

controller.cpp

#include 

#include "controller.h"
#include "rep_commoninterface_source.h"

Controller::Controller(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    init();

    startTimer(1000);
}

void Controller::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event)
//    if (m_pInterface->isValid())
//        ui.label->setText("connected");
//    else
//        ui.label->setText("disconnected");
}

void Controller::on_accelerate_clicked()
{
    m_pInterface->sendMsg(CommonInterfaceSource::Accelerate);
}

void Controller::on_decelerate_clicked()
{
   m_pInterface->sendMsg(CommonInterfaceSource::Decelerate);
}

void Controller::on_left_clicked()
{
    m_pInterface->sendMsg(CommonInterfaceSource::TurnLeft);
}

void Controller::on_right_clicked()
{
    m_pInterface->sendMsg(CommonInterfaceSource::TurnRight);
}

void Controller::init()
{
    m_pHost = new QRemoteObjectHost(this);
    m_pHost->setHostUrl(QUrl("local:interfaces"));
    m_pInterface = new CommonInterface(this);
    m_pHost->enableRemoting(m_pInterface);
}

main.cpp

#include 

#include "controller.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Controller controller;
    controller.show();
    return app.exec();
}

controller.ui
Qt Remote Object(QtRO)实现进程间通信——遥控小车(二)_第2张图片
是在官方的代码上改的:
Qt Remote Object(QtRO)实现进程间通信——遥控小车(二)_第3张图片
全部代码在这里:
链接:https://pan.baidu.com/s/1dCDiPNIqRHOTze_NrvLDSg
提取码:ir63

参考:QtRO rep中定义枚举类型要避免的坑

你可能感兴趣的:(QT)