因此,该程序使用操纵杆工作,数据从操纵杆输出到接口并通过 Modbus 传输。为此,决定将来自操纵杆的数据接收和处理放到一个单独的线程中。一个单独的类被设计在joyhid.h
:
#ifndef JOYHID_H
#define JOYHID_H
#include <QObject>
#include <cstdint>
#include "hidapi.h"
typedef struct _HID_JOYSTK_Info
{
uint16_t X;
uint16_t Y;
uint16_t Z;
uint16_t X_low;
uint16_t Y_low;
uint8_t buttons[5];
}
HID_JOYSTK_Info_TypeDef;
class JoyHID : public QObject
{
Q_OBJECT
public:
explicit JoyHID(QObject *parent = nullptr);
public slots:
void joySlot();
signals:
void joySignal(HID_JOYSTK_Info_TypeDef *obj);
private:
void joyHIDUpdate(HID_JOYSTK_Info_TypeDef *obj);
};
#endif // JOYHID_H
它mainwindow.cpp
被扔到一个单独的线程中:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QThread *joy_thread = new QThread;
JoyHID *joystck = new JoyHID;
joystck->moveToThread(joy_thread);
connect(joy_thread, SIGNAL(started()), joystck, SLOT(joySlot()));
connect(joystck, &JoyHID::joySignal, this, &MainWindow::uiSlot);
joy_thread->start();
}
下面的简单代码在joyhid.cpp
slot中执行:joySlot()
void JoyHID::joySlot()
{
joyHIDUpdate(&joyInfo);
emit joySignal(&joyInfo);
}
处理了一次迭代,我得到了一次值的更新。但我需要流不断地旋转,从喜悦中更新价值观。joySlot()
例如,第一个想法是放入slot while(true)
,但这个想法失败了。该应用程序紧紧地挂着。实际上,问题是,我的解决方案有哪些可行的替代方案,在这种情况下应用什么更好?
无限的 while(true) 循环阻塞线程的事件循环并且不再处理事件/信号。最简单的方法是在循环中触发事件处理:
或在插槽末尾重新发出信号(它将排队等待处理并在其他所有操作之后处理)
joihid.h
joihid.cpp
更好的是,将您的类视为有限状态机(请参阅QStateMachine)。这将是最美丽最正确的
作为替代方案,我可以建议使用计时器,以便在给定的时间间隔内发出一次具有操纵杆状态的信号。在你的构造函数中
JoyHID
是这样的:顺便说一句,使用这种方法,如果仅需要 joySlot 方法来服务于信号的发射,则可以将其替换为 lambda: