由于无线鼠标忘记带回家了,想躺在床上看电视(电视机屏幕当显示器)怎么办呢?HOHO,我们的手机屏幕本来就是个触摸板,嘿嘿,那就用手机屏幕当鼠标好了。
大致的思路就是电脑和手机用Tcp通信,毕竟是都连着路由器的。主要用到的模块就是QTcpServer,QTcpSocket.
#include <QObject>
#include <QSystemTrayIcon>
class Widget;
class QTcpServer;
class QTcpSocket;
class controller : public QObject
{
Q_OBJECT
public:
explicit controller(QObject *parent = 0);
typedef enum{mouseMove,mouseSingleClick,mouseDoubleClick,mouseRightClick} mouseAction;
~controller();
private:
QTcpServer* tcpserver;
QTcpSocket* clientSocket;
quint16 blockSize;
Widget* widget;
QSystemTrayIcon* sysIcon;
private:
void TranslateMessage();
public slots:
void onConnected();
void onReadyRead();
void onDisConnected();
void onSysIconActRe(QSystemTrayIcon::ActivationReason reason);
#include "controller.h"
#include <QTcpSocket>
#include <QTcpServer>
#include <QDataStream>
#include <windows.h>
#include "widget.h"
#include <QHostAddress>
controller::controller(QObject *parent) : QObject(parent)
{
tcpserver = new QTcpServer(this);
widget = new Widget;
widget->show();
sysIcon = new QSystemTrayIcon(this);
sysIcon->setIcon(QIcon(":/computer_16px.ico"));
sysIcon->hide();
sysIcon->setToolTip("工作中");
// installEventFilter(sysIcon);
tcpserver->listen(QHostAddress::Any,15333); //监听15333端口
blockSize = 0;
connect(tcpserver,SIGNAL(newConnection()),SLOT(onConnected()));
connect(widget,SIGNAL(sg_hide()),sysIcon,SLOT(show()));
connect(sysIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
SLOT(onSysIconActRe(QSystemTrayIcon::ActivationReason)));
}
void controller::onReadyRead()
{
QDataStream in(clientSocket);
in.setVersion(QDataStream::Qt_5_8);
while(clientSocket->bytesAvailable()>=sizeof(quint16)){
if(blockSize==0) in>>blockSize;
if(clientSocket->bytesAvailable()<blockSize) break;
TranslateMessage();
// widget->appendLog("收到消息");
blockSize=0;
}
}
void controller::TranslateMessage()
{
QDataStream in(clientSocket);
in.setVersion(QDataStream::Qt_5_8);
qint16 actionType;
in>>actionType;
// DWORD dx,dy;
int px,py;
switch(actionType){
case mouseMove:
in>>px>>py;
// dx = px*GetSystemMetrics(SM_CXSCREEN);
// dy = py*GetSystemMetrics(SM_CYSCREEN);
mouse_event(MOUSEEVENTF_MOVE,px,py,0,0);
// qDebug()<<dx<<dy;
break;
case mouseSingleClick:
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
break;
case mouseDoubleClick:
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
break;
case mouseRightClick:
mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
break;
}
}
void controller::onConnected()
{
clientSocket = tcpserver->nextPendingConnection();
connect(clientSocket,SIGNAL(readyRead()),SLOT(onReadyRead()));
connect(clientSocket,SIGNAL(disconnected()),SLOT(onDisConnected()));
widget->appendLog("建立连接!");
widget->appendLog("客户IP:"+clientSocket->peerAddress().toString());
widget->appendLog("客户名:"+clientSocket->peerName());
}
void controller::onDisConnected()
{
widget->appendLog("断开连接!");
clientSocket->deleteLater();
}
controller::~controller()
{
widget->deleteLater();
}
void controller::onSysIconActRe(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::DoubleClick){
widget->show();
sysIcon->hide();
}
}
这是PC端的主要代码 , 界面用的是之前写的模板。
下面是安卓端的,就更简单了,主要就是一个触摸区域和鼠标左右键。
#include <QDialog>
class QTcpSocket;
class QTimer;
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
enum{mouseMove,mouseSingleClick,mouseDoubleClick,mouseRightClick};
private:
Ui::Dialog *ui;
QTcpSocket* tcpSocket;
QPoint move_pre_position;
QTimer* clickTimer;
public slots:
void onBtn_connectClicked();
void onBtn_disconnectClicked();
void onClick_TimerRunout();
void onConnected();
void onDisconnected();
void onBtn_LeftClicked();
void onBtn_RightClicked();
protected:
void mouseMoveEvent(QMouseEvent*);
void mousePressEvent(QMouseEvent*);
};
#include "dialog.h"
#include "ui_dialog.h"
#include <QTcpSocket>
#include <QHostAddress>
#include <QMouseEvent>
#include <QDataStream>
#include <QTimer>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
showFullScreen();
tcpSocket = new QTcpSocket(this);
tcpSocket->bind(ui->lineEdit_port->text().toInt());
connect(ui->btn_connect,SIGNAL(clicked(bool)),SLOT(onBtn_connectClicked()));
clickTimer = new QTimer(this);
clickTimer->setInterval(100);
clickTimer->setSingleShot(true);
connect(clickTimer,SIGNAL(timeout()),SLOT(onClick_TimerRunout()));
connect(tcpSocket,SIGNAL(connected()),SLOT(onConnected()));
connect(tcpSocket,SIGNAL(disconnected()),SLOT(onDisconnected()));
connect(ui->btn_disconnect,SIGNAL(clicked(bool)),SLOT(onBtn_disconnectClicked()));
connect(ui->Btn_Left,SIGNAL(clicked(bool)),SLOT(onBtn_LeftClicked()));
connect(ui->Btn_Right,SIGNAL(clicked(bool)),SLOT(onBtn_RightClicked()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::onBtn_connectClicked()
{
tcpSocket->connectToHost(QHostAddress(ui->lineEdit_ip->text()),ui->lineEdit_port->text().toInt());
}
void Dialog::onBtn_disconnectClicked()
{
tcpSocket->disconnectFromHost();
}
void Dialog::mouseMoveEvent(QMouseEvent* event)
{
if(tcpSocket->state() == QAbstractSocket::ConnectedState){
QPoint movePos = event->pos() - move_pre_position;
int move_x,move_y;
move_x = movePos.x();
move_y = movePos.y();
QByteArray data;
QDataStream out(&data,QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_8);
out<<quint16(0)<<(qint16)mouseMove<<move_x<<move_y;
out.device()->seek(0);
out<<(quint16)(data.size()-sizeof(quint16));
tcpSocket->write(data);
move_pre_position = event->pos();
// ui->textBrowser->append(QVariant(move_x).toString()+QVariant(move_y).toString());
}
}
void Dialog::mousePressEvent(QMouseEvent *event)
{
move_pre_position = event->pos(); //记录当前位置
}
void Dialog::onClick_TimerRunout()
{
QByteArray data;
QDataStream out(&data,QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_8);
out<<quint16(0)<<(qint16)mouseSingleClick;
out.device()->seek(0);
out<<(quint16)(data.size()-sizeof(quint16));
tcpSocket->write(data);
}
void Dialog::onConnected()
{
ui->textBrowser->append("连接电脑成功!");
ui->textBrowser->append("电脑名:"+tcpSocket->peerName());
}
void Dialog::onDisconnected()
{
ui->textBrowser->append("已断开连接");
}
void Dialog::onBtn_LeftClicked()
{
if(tcpSocket->state() == QAbstractSocket::ConnectedState){
QByteArray data;
QDataStream out(&data,QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_8);
if(clickTimer->isActive()){
out<<quint16(0)<<(qint16)mouseDoubleClick;
clickTimer->stop();
out.device()->seek(0);
out<<(quint16)(data.size()-sizeof(quint16));
tcpSocket->write(data);
}
else{
clickTimer->start(); //双击单击判断
}
}
}
void Dialog::onBtn_RightClicked()
{
if(tcpSocket->state() == QAbstractSocket::ConnectedState){
QByteArray data;
QDataStream out(&data,QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_8);
out<<quint16(0)<<(qint16)mouseRightClick;
clickTimer->stop();
out.device()->seek(0);
out<<(quint16)(data.size()-sizeof(quint16));
tcpSocket->write(data);
}
}
由于之前写过一个仿QQ的聊天程序(也就基本的聊天功能啦),这次几乎没碰到问题。主要会发生的问题就是TcpSocket的读写,可以参考上面的onReadyRead函数。(因为Tcp可能一下接到几条消息,会粘连所以要注意)。还有就是我不知道Qt有没有自带的函数可以实现任意区域的鼠标事件,我用的是windows的函数, mouse_event.
下面贴下运行效果啦: