Leap Motion数据获取很简单,但我们在做项目时,往往希望将其完全抽象掉。我不想知道如何打开Leap Motion的,不想了解Leap运作机制,我只要Leap能给我数据,我处理就是了。之所以选择使用Qt,因为Qt越来越被广泛使用,并且自己工作也天天玩这个。但对于UDP,是第一次接触,这里先贡献第一版本代码,以后会改进。
2013-12-10 Ver0.9 粗陋版本 CSDN下载地址
先给出UDP接收端代码
.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class QUdpSocket; class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); protected slots: void recvUdpData(); private: QUdpSocket *m_udpSocket; Ui::MainWindow *ui; }; #endif // MAINWINDOW_H |
.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QUdpSocket> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); m_udpSocket = new QUdpSocket; m_udpSocket->bind(QHostAddress::LocalHost,8000); connect(m_udpSocket,SIGNAL(readyRead()),this,SLOT(recvUdpData())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::recvUdpData() { char data[100]; m_udpSocket->readDatagram(data,100); qDebug()<<"udp receive : "<<data; if(ui->listWidget->count() > 50) { ui->listWidget->takeItem(ui->listWidget->count()-1); // ui->listWidget->clear(); // QListWidgetItem *pItem = ui->listWidget->item(ui->listWidget->count()-1); //ui->listWidget->removeItemWidget(pItem); } static int count = 0; ++count; if(count > 9999) { count = 0; } ui->listWidget->insertItem(0,QString("%1 ").arg(count,4,10,QChar('0')) + QString(data)); } |
下来时发送端(服务器)代码
.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#ifndef LEAPDATAWIDGET_H #define LEAPDATAWIDGET_H #include <QWidget> #include "Leap.h" using namespace Leap; namespace Ui { class CLeapDataWidget; } class QUdpSocket; class CLeapDataWidget : public QWidget,public Listener { Q_OBJECT public: explicit CLeapDataWidget(QWidget *parent = 0); ~CLeapDataWidget(); void BindController(Controller *control); protected slots: void sendFrameData(QByteArray array); void stopLeapMotionController(); private: Ui::CLeapDataWidget *ui; QUdpSocket *m_udpSocket; Controller *m_pController; virtual void onInit(const Controller &controller); virtual void onConnect(const Controller& controller); virtual void onDisconnect(const Controller &controller); virtual void onExit(const Controller &controller); virtual void onFrame(const Controller &controller); virtual void onFocusGained(const Controller &controller); virtual void onFocusLost(const Controller &controller); }; #endif // LEAPDATAWIDGET_H |
.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
#include "LeapDataWidget.h" #include "ui_LeapDataWidget.h" #include <QDebug> #include <QUdpSocket> const qint16 DefaultSendPort = 8000; CLeapDataWidget::CLeapDataWidget(QWidget *parent) : QWidget(parent), ui(new Ui::CLeapDataWidget) { ui->setupUi(this); connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(stopLeapMotionController())); m_udpSocket = new QUdpSocket; m_udpSocket->bind(QHostAddress::LocalHost,9000); } CLeapDataWidget::~CLeapDataWidget() { delete ui; } void CLeapDataWidget::BindController(Controller *control) { m_pController = control; } void CLeapDataWidget::sendFrameData(QByteArray array) { //qDebug()<<array; m_udpSocket -> writeDatagram(array,QHostAddress::LocalHost,DefaultSendPort); } void CLeapDataWidget::stopLeapMotionController() { m_pController->removeListener(*this); } void CLeapDataWidget::onInit(const Controller &controller) { controller.setPolicyFlags(Controller::POLICY_BACKGROUND_FRAMES); std::cout << "Initialized" << std::endl; } void CLeapDataWidget::onConnect(const Controller &controller) { std::cout << "Connected" << std::endl; controller.enableGesture(Gesture::TYPE_CIRCLE); controller.enableGesture(Gesture::TYPE_KEY_TAP); controller.enableGesture(Gesture::TYPE_SCREEN_TAP); controller.enableGesture(Gesture::TYPE_SWIPE); } void CLeapDataWidget::onDisconnect(const Controller &controller) { //Note: not dispatched when running in a debugger. std::cout << "Disconnected" << std::endl; } void CLeapDataWidget::onExit(const Controller &controller) { std::cout << "Exited" << std::endl; } void CLeapDataWidget::onFrame(const Controller &controller) { // Get the most recent frame and report some basic information QCoreApplication::processEvents(); // emit sigTest(); const Frame frame = controller.frame(); // std::cout << "Frame id: " << frame.id() // << ", timestamp: " << frame.timestamp() // << ", hands: " << frame.hands().count() // << ", fingers: " << frame.fingers().count() // << ", tools: " << frame.tools().count() // << ", gestures: " << frame.gestures().count() << std::endl; if (!frame.hands().isEmpty()) { // Get the first hand const Hand hand = frame.hands()[0]; // Check if the hand has any fingers const FingerList fingers = hand.fingers(); if (!fingers.isEmpty()) { // Calculate the hand's average finger tip position Vector avgPos; for (int i = 0; i < fingers.count(); ++i) { //avgPos += fingers[i].tipPosition(); QString tip_pos_str = QString("Start id=%1 x=%2 y=%3 End\n").arg((int)fingers[i].id()).arg((int)fingers[i].tipPosition().x).arg((int)fingers[i].tipPosition().y); QByteArray array = qPrintable(tip_pos_str); sendFrameData(array); // qDebug()<<fingers[i].tipPosition().x; // qDebug()<<tip_pos_str; } // avgPos /= (float)fingers.count(); // std::cout << "Hand has " << fingers.count() // << " fingers, average finger tip position" << avgPos << std::endl; } // Get the hand's sphere radius and palm position // std::cout << "Hand sphere radius: " << hand.sphereRadius() // << " mm, palm position: " << hand.palmPosition() << std::endl; // Get the hand's normal vector and direction // const Vector normal = hand.palmNormal(); // const Vector direction = hand.direction(); // Calculate the hand's pitch, roll, and yaw angles // std::cout << "Hand pitch: " << direction.pitch() * RAD_TO_DEG << " degrees, " // << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, " // << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl; } // Get gestures const GestureList gestures = frame.gestures(); for (int g = 0; g < gestures.count(); ++g) { Gesture gesture = gestures[g]; switch (gesture.type()) { case Gesture::TYPE_CIRCLE: { CircleGesture circle = gesture; std::string clockwiseness; if (circle.pointable().direction().angleTo(circle.normal()) <= PI/4) { clockwiseness = "clockwise"; } else { clockwiseness = "counterclockwise"; } // Calculate angle swept since last frame float sweptAngle = 0; if (circle.state() != Gesture::STATE_START) { CircleGesture previousUpdate = CircleGesture(controller.frame(1).gesture(circle.id())); sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * PI; } // std::cout << "Circle id: " << gesture.id() // << ", state: " << gesture.state() // << ", progress: " << circle.progress() // << ", radius: " << circle.radius() // << ", angle " << sweptAngle * RAD_TO_DEG // << ", " << clockwiseness << std::endl; QString circle_gesture = QString("Gesture=Circure"); QByteArray array = qPrintable(circle_gesture); sendFrameData(array); break; } case Gesture::TYPE_SWIPE: { SwipeGesture swipe = gesture; // std::cout << "Swipe id: " << gesture.id() // << ", state: " << gesture.state() // << ", direction: " << swipe.direction() // << ", speed: " << swipe.speed() << std::endl; QString swipe_gesture = QString("Gesture=Swipe,Direction=(%1,%2),Speed=%3").arg(swipe.direction().x).arg(swipe.direction().y).arg(swipe.speed() ); QByteArray array = qPrintable(swipe_gesture); sendFrameData(array); break; } case Gesture::TYPE_KEY_TAP: { KeyTapGesture tap = gesture; // std::cout << "Key Tap id: " << gesture.id() // << ", state: " << gesture.state() // << ", position: " << tap.position() // << ", direction: " << tap.direction()<< std::endl; QString tap_gesture = QString("Gesture=Keytap,Position=(%1,%2)").arg(tap.position().x).arg(tap.position().y); QByteArray array = qPrintable(tap_gesture); sendFrameData(array); break; } case Gesture::TYPE_SCREEN_TAP: { ScreenTapGesture screentap = gesture; // std::cout << "Screen Tap id: " << gesture.id() // << ", state: " << gesture.state() // << ", position: " << screentap.position() // << ", direction: " << screentap.direction()<< std::endl; QString tap_gesture = QString("Gesture=Sceentap,Position=(%1,%2)").arg(screentap.position().x).arg(screentap.position().y); QByteArray array = qPrintable(tap_gesture); sendFrameData(array); break; } default: std::cout << "Unknown gesture type." << std::endl; break; } } if (!frame.hands().isEmpty() || !gestures.isEmpty()) { std::cout << std::endl; } } void CLeapDataWidget::onFocusGained(const Controller &controller) { std::cout << "Focus Gained" << std::endl; } void CLeapDataWidget::onFocusLost(const Controller &controller) { std::cout << "Focus Lost" << std::endl; } |
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include "LeapDataWidget.h" #include <QApplication> #include <QDebug> #include <Windows.h> #include <iostream> int main(int argc, char *argv[]) { QApplication a(argc, argv); CLeapDataWidget w; w.move(0,0); w.show(); // Create a sample listener and controller //SampleListener listener; Controller controller; w.BindController(&controller); // Have the sample listener receive events from the controller controller.addListener(w); std::cout << "Press Enter to quit..." << std::endl; std::cin.get(); // controller.removeListener(w); return a.exec(); } |
特别的.pro文件(如何在Qt中导入Leap.lib,参照CSDN文章)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#------------------------------------------------- # # Project created by QtCreator 2013-12-06T00:31:59 # #------------------------------------------------- LIBS += -LF:\Softs\Qt\Qt-Projects\QtForLeapMotion\lib -lLeap #LIBS += -Llib -lLeap QT += core gui QT += network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = QtForLeapMotion TEMPLATE = app SOURCES += main.cpp\ LeapDataWidget.cpp HEADERS += LeapDataWidget.h \ LeapMath.h \ Leap.h FORMS += LeapDataWidget.ui |