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
是在官方的代码上改的:
全部代码在这里:
链接:https://pan.baidu.com/s/1dCDiPNIqRHOTze_NrvLDSg
提取码:ir63
参考:QtRO rep中定义枚举类型要避免的坑