我正在开发一个多线程应用程序,我需要通过 modbus 实例化 n 个设备。所以我创建了一个控制器(ServiceSM)来实例化 N 个线程(ServiceSlots)。
设备多种多样,因此我必须为每种类型的设备创建“驱动程序”,其中一个驱动程序使用 QModbusClient 类,因此我创建了一个控制器来管理设备类型。
为了测试状态机的操作和与设备的连接,我制作了一个示例代码以在图形界面中运行。
我删除了一些无关紧要的代码片段,以便更容易理解
在 MD4040driver 类中,当我的代码运行此部分时,会出现以下消息。如果我在图形界面中实例化 DeviceDriver 类,它可以完美运行,当我在线程中实例化它时会出现问题。
打电话时
modbusDevice->connectDevice()
MD4040drive::sm_conn() - 尝试连接 - 这是我的消息错误:
QObject::connect: 无法对“QModbusDevice::State”类型的参数进行排队(确保使用 qRegisterMetaType() 注册了“QModbusDevice::State”。)
QObject:无法为不同线程中的父级创建子级。(Parent是QTcpSocket(0x24a6ce8),parent的线程是ServiceSlots(0xea66488),当前线程是QThread(0x2418a78)
QObject:无法为不同线程中的父级创建子级。(Parent是QTcpSocket(0x24a6ce8),parent的线程是ServiceSlots(0xea66488),当前线程是QThread(0x2418a78)
void MD4040drive::sm_conn()
{
if (modbusDevice->state() != QModbusDevice::ConnectedState) {
modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, this->cfg.modbus.porta );
modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, this->cfg.modbus.ip);
modbusDevice->setTimeout( this->cfg.modbus.timeout );
modbusDevice->setNumberOfRetries(this->cfg.modbus.retries);
qDebug() << "MD4040drive::sm_conn() - try connect";
if (!modbusDevice->connectDevice()) {
qDebug() << "Erro: " << modbusDevice->errorString();
} else {
qDebug() << "Aguardando conexão...";
}
}
else{
//already connected...
this->getDados_NO_TH();
}
}
休息我的代码(部分)
devicedriverviewgui.h devicedriverviewgui.cpp
class DeviceDriverViewGUI : public QDialog
{
Q_OBJECT
public:
explicit DeviceDriverViewGUI(QWidget *parent = 0);
~DeviceDriverViewGUI();
private slots:
void on_pbTry_clicked();
private:
Ui::DeviceDriverViewGUI *ui;
ServiceSlots *serviceSlot;
};
void DeviceDriverViewGUI::on_pbTry_clicked()
{
Equip equip_try = Equip();
serviceSlot = new ServiceSlots();
serviceSlot->setEquipamento(equip_try);
serviceSlot->start();
}
服务槽.h 服务槽.cpp
class ServiceSlots : public QThread
{
Q_OBJECT
public:
ServiceSlots();
void run();
private:
QTimer *timer;
DeviceDriver *device;
private slots:
void sm_getData();
void device_response(bool boEnd);
};
void ServiceSlots::run()
{
int e;
eventLoop = new QEventLoop();
timer = new QTimer();
connect(timer, SIGNAL(timeout()),this, SLOT(sm_controler()));
timer->start(TICK_SM_SLOT);
this->device = new DeviceDriver();
e = eventLoop->exec();
qDebug() << "Exit loop"<< e;
}
void ServiceSlots::sm_controler()
{
if(this->idleState){;}
else{
this->sm_getData();
this->idleState = true;
}
}
void ServiceSlots::sm_getData()
{
connect(device,SIGNAL(end(bool)),this,SLOT(device_response(bool)));
device->requestDeviceDriver(&this->equipamento,&this->next_date);
}
设备驱动程序.h 设备驱动程序.cpp
class DeviceDriver : public QObject
{
Q_OBJECT
public:
DeviceDriver();
void requestDeviceDriver(Equip *equip,QDateTime *date);
private:
//Drivers de dispositivos..
MD4040drive *md4040;
private slots:
//Request data to driver...
void request();
signals:
void end(bool boEnd);
};
void DeviceDriver::request()
{
connect(md4040,SIGNAL(end(bool)),this,SLOT(md4040_end(bool)));
this->md4040->requestMD4040drive(&this->equip,&this->date);
}
DeviceDriver::DeviceDriver(){
----
md4040 = new MD4040drive();
---
}
void DeviceDriver::requestDeviceDriver(Equip *equip, QDateTime *date){
this->equip = *equip;
this->date = *date;
this->request();
}
md4040drive.h md4040drive.cpp
class MD4040drive : public QObject // QObject//public QObject QRunnable QThread
{
Q_OBJECT
public:
explicit MD4040drive(QObject *parent = 0);
~MD4040drive();
void requestMD4040drive(Equip *equip,QDateTime *date);
private:
void run();
QModbusClient *modbusDevice;
private slots:
void m_conn();
signals:
void end(bool boRun);
};
MD4040drive::MD4040drive(QObject *parent): QObject(parent)
{
modbusDevice = new QModbusTcpClient();
connect(modbusDevice, &QModbusClient::stateChanged,this, &MD4040drive::onStateChanged);
}
void MD4040drive::requestMD4040drive(Equip *equip, QDateTime *date)
{
this->equip = *equip;
this->date = *date;
this->run();
}
void MD4040drive::run()
{
this->sm_conn();
}
void MD4040drive::sm_conn()
{
if (modbusDevice->state() != QModbusDevice::ConnectedState) {
modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, this->cfg.modbus.porta );
modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, this->cfg.modbus.ip);
modbusDevice->setTimeout( this->cfg.modbus.timeout );
modbusDevice->setNumberOfRetries(this->cfg.modbus.retries);
qDebug() << "MD4040drive::sm_conn() - try connect";
if (!modbusDevice->connectDevice()) {
qDebug() << "Erro: " << modbusDevice->errorString();
} else {
qDebug() << "Aguardando conexão...";
}
}
else{
//already connected...
this->getDados_NO_TH();
}
}