以前做了一个小东西,通过手机来控制PPT的翻页,最大化和最小化,东西很简单,近期整理电脑发现了拿来和大家分享一下 
主要分为两个部分,客户端和服务器 
客户端实现 
当初考虑到跨平台的特性就选择了qt来写的,代码很简单,主要是通过socket连接运行在电脑上的server,发送不同的指令完成不同的操作。由于Qt的跨平台性可以将其移植到安卓iOS上,安卓上使用完全没问题,ios也应该是没问题,我不是土豪,没法用苹果手机测试,有兴趣的大家可以试试 
Control_PPT.pro

  1. #-------------------------------------------------
  2. #
  3. # Project created by QtCreator 2016-06-20T09:20:20
  4. #
  5. #-------------------------------------------------
  6. QT += core gui
  7. QT += network
  8. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  9. TARGET = Control_PPT
  10. TEMPLATE = app
  11. SOURCES += main.cpp\
  12. mainwidget.cpp
  13. HEADERS += mainwidget.h

mainwidget.h

  1. #ifndef MAINWIDGET_H
  2. #define MAINWIDGET_H
  3. #include <QWidget>
  4. #include <QtNetwork/QtNetwork>
  5. #include <QLabel>
  6. #include <QPushButton>
  7. #include <QLineEdit>
  8. #include <QVBoxLayout>
  9. #include <QHBoxLayout>
  10. #include <QGridLayout>
  11. #include <QMessageBox>
  12. #include <QMouseEvent>
  13. #include <QStatusBar>
  14. class MainWidget : public QWidget
  15. {
  16. Q_OBJECT
  17. public:
  18. MainWidget(QWidget *parent = 0);
  19. ~MainWidget();
  20. void initIpLayout();
  21. void initControlBtnLayout();
  22. // void mouseMoveEvent(QMouseEvent *event);
  23. private:
  24. QLabel *ipLbl;
  25. QLineEdit *ipLineEdit;
  26. QPushButton *connectBtn;
  27. /*
  28. 控制按钮 上一页、写一页等
  29. */
  30. QPushButton *upBtn;
  31. QPushButton *downBtn;
  32. QPushButton *leftBtn;
  33. QPushButton *rightBtn;
  34. QPushButton *f5Btn;
  35. QPushButton *escBtn;
  36. /*
  37. 布局
  38. */
  39. QHBoxLayout *ipHLayout;
  40. QGridLayout *controlBtnLayout;
  41. QVBoxLayout *mainVLayout;
  42. QTcpSocket *client;
  43. QStatusBar *statusBar;
  44. QLabel *msgLabel;
  45. bool flag;
  46. public slots:
  47. void conncSlot();
  48. void upSlot();
  49. void downSlot();
  50. void leftSlot();
  51. void rightSlot();
  52. void f5Slot();
  53. void escSlot();
  54. void displayError(QAbstractSocket::SocketError);
  55. };
  56. #endif // MAINWIDGET_H

main.widget.cpp

  1. #include "mainwidget.h"
  2. MainWidget::MainWidget(QWidget *parent)
  3. : QWidget(parent)
  4. {
  5. flag = true;
  6. msgLabel = new QLabel;
  7. //msgLabel->setMinimumSize(msgLabel->sizeHint());
  8. msgLabel->setAlignment(Qt::AlignHCenter);
  9. statusBar = new QStatusBar(this);
  10. statusBar->setFixedHeight(30);
  11. statusBar->setFixedWidth(this->width());
  12. statusBar->addWidget(msgLabel); //头文件要添加include<QStatusBar>才不会报错
  13. initIpLayout();
  14. initControlBtnLayout();
  15. mainVLayout = new QVBoxLayout;
  16. mainVLayout->addLayout(ipHLayout);
  17. mainVLayout->addLayout(controlBtnLayout);
  18. this->setLayout(mainVLayout);
  19. connect(connectBtn,SIGNAL(clicked()),this, SLOT(conncSlot()));
  20. connect(upBtn,SIGNAL(clicked()),this, SLOT(upSlot()));
  21. connect(downBtn,SIGNAL(clicked()),this, SLOT(downSlot()));
  22. connect(f5Btn,SIGNAL(clicked()),this, SLOT(f5Slot()));
  23. connect(leftBtn,SIGNAL(clicked()),this, SLOT(leftSlot()));
  24. connect(rightBtn,SIGNAL(clicked()),this, SLOT(rightSlot()));
  25. connect(escBtn,SIGNAL(clicked()),this, SLOT(escSlot()));
  26. }
  27. /*
  28. 设置获取ip连接的布局
  29. */
  30. void MainWidget::initIpLayout()
  31. {
  32. ipLbl = new QLabel(tr("IP:"));
  33. ipLineEdit = new QLineEdit();
  34. ipLineEdit->setPlaceholderText(tr("127.0.0.1"));
  35. connectBtn = new QPushButton(tr("连接"));
  36. ipHLayout = new QHBoxLayout;
  37. ipHLayout->addWidget(ipLbl);
  38. ipHLayout->addWidget(ipLineEdit);
  39. ipHLayout->addWidget(connectBtn);
  40. // ipHLayout->setMargin(10);
  41. }
  42. void MainWidget::initControlBtnLayout()
  43. {
  44. upBtn = new QPushButton(tr("上"));
  45. leftBtn = new QPushButton(tr("左"));
  46. f5Btn = new QPushButton(tr("f5"));
  47. rightBtn = new QPushButton(tr("右"));
  48. downBtn = new QPushButton(tr("下"));
  49. escBtn = new QPushButton(tr("esc"));
  50. controlBtnLayout = new QGridLayout();
  51. controlBtnLayout->addWidget(upBtn,0,1);
  52. controlBtnLayout->addWidget(leftBtn, 1, 0);
  53. controlBtnLayout->addWidget(f5Btn,1,1);
  54. controlBtnLayout->addWidget(rightBtn, 1, 2);
  55. controlBtnLayout->addWidget(downBtn, 2, 1);
  56. controlBtnLayout->addWidget(escBtn, 3, 1);
  57. }
  58. //void MainWidget::mouseMoveEvent(QMouseEvent *event)
  59. //{
  60. // int x = event->x();
  61. // int y = event->y();
  62. // QPoint point = cursor().pos();
  63. // int x = point.x();
  64. // int y = point.y();
  65. // QString xy;
  66. // xy.clear();
  67. // xy = tr("%1%2%3").arg(x).arg("#").arg(y);
  68. // qDebug() << xy;
  69. // char* chxy;
  70. // QByteArray ba = xy.toLatin1();
  71. // chxy=ba.data();
  72. // if(flag)
  73. // client->write(chxy);
  74. //}
  75. void MainWidget::displayError(QAbstractSocket::SocketError)
  76. {
  77. flag = false;
  78. qDebug() << client->errorString(); //输出错误信息
  79. }
  80. void MainWidget::conncSlot()
  81. {
  82. QString ip = ipLineEdit->text();
  83. QString pattern("^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])[.](\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])[.](\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])[.](\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$");
  84. QRegExp rx(pattern);
  85. if(ip.isEmpty())
  86. {
  87. QMessageBox::information(this,"请输入IP","请输入服务器的IP地址!");
  88. return ;
  89. }
  90. else if(!(rx.exactMatch(ip)))
  91. {
  92. QMessageBox::information(this,"格式错误","请输入正确的IP地址!");
  93. return ;
  94. }
  95. client = new QTcpSocket(this);
  96. client->connectToHost(QHostAddress(ip), 5588);
  97. //connect(client, SIGNAL(connected()),this, SLOT(is_connect_ok()));
  98. connect(client,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError)));
  99. if(flag)
  100. {
  101. msgLabel->setText(tr("连接成功!"));
  102. QMessageBox::information(this,tr("连接提示"),tr("恭喜你连接成功"));
  103. flag = false;
  104. }
  105. else
  106. {
  107. msgLabel->setText(tr("连接失败!"));
  108. QMessageBox::information(this,tr("连接提示"),tr("连接失败,请检查ip是否正确"));
  109. }
  110. ipLineEdit->clear();
  111. }
  112. void MainWidget::escSlot()
  113. {
  114. client->write("esc");
  115. msgLabel->setText(tr("退出全屏显示"));
  116. //client->write("100#100");
  117. }
  118. void MainWidget::upSlot()
  119. {
  120. client->write("up");
  121. msgLabel->setText(tr("上一页!"));
  122. }
  123. void MainWidget::downSlot()
  124. {
  125. msgLabel->setText(tr("下一页!"));
  126. client->write("down");
  127. }
  128. void MainWidget::leftSlot()
  129. {
  130. msgLabel->setText(tr("上一页!"));
  131. client->write("left");
  132. }
  133. void MainWidget::rightSlot()
  134. {
  135. msgLabel->setText(tr("下一页!"));
  136. client->write("right");
  137. }
  138. void MainWidget::f5Slot()
  139. {
  140. msgLabel->setText(tr("全屏显示!"));
  141. client->write("f5");
  142. }
  143. MainWidget::~MainWidget()
  144. {
  145. }

main.cpp

  1. #include "mainwidget.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. MainWidget w;
  7. w.show();
  8. return a.exec();
  9. }

服务器端 
服务器端是Python写的,当然用c++也是可以的,考虑到代码的简洁就选择了python,正好当时刚学了几点的python就用了它,代码写的很烂。服务器的作用主要是调用微软提供的PPT接口完成操作。 
server.py

  1. # Echo server program
  2. from socket import*
  3. from time import ctime
  4. import win32com.client
  5. import win32api
  6. import win32con
  7. import time
  8. import pythoncom
  9. from ctypes import *
  10. class PowerPointControler:
  11. def __init__(self):
  12. pythoncom.CoInitialize()
  13. self.app = win32com.client.Dispatch("PowerPoint.Application")
  14. def fullScreen(self):
  15. #全屏播放
  16. if self.hasActivePresentation():
  17. #使用Run方法创建一个新的幻灯片放映窗口并将其添加到SlideShowWindows集合
  18. self.app.ActivePresentation.SlideShowSettings.Run()#该方法用于运行指定演示文稿的幻灯片放映。
  19. return self.getActivePresentationSlideIndex()
  20. def closeFull(self):#结束第一个幻灯片放映窗口中的幻灯片放映
  21. if self.app.ActivePresentation.SlideShowSettings.Run():
  22. self.app.SlideShowWindows(1).View.Exit()
  23. def gotoSlide(self,index):
  24. #跳转到指定的页面
  25. if self.hasActivePresentation():
  26. try:
  27. self.app.ActiveWindow.View.GotoSlide(index)
  28. return self.app.ActiveWindow.View.Slide.SlideIndex
  29. except:
  30. self.app.SlideShowWindows(1).View.GotoSlide(index)
  31. return self.app.SlideShowWindows(1).View.CurrentShowPosition
  32. def nextPage(self):#下一页ppt
  33. if self.hasActivePresentation():
  34. count = self.getActivePresentationSlideCount()
  35. index = self.getActivePresentationSlideIndex()
  36. return count if index >= count else self.gotoSlide(index+1)
  37. def prePage(self):#上一页ppt
  38. if self.hasActivePresentation():
  39. index = self.getActivePresentationSlideIndex()
  40. return index if index <= 1 else self.gotoSlide(index-1)
  41. def drawLine(self, x, y):
  42. index = self.getActivePresentationSlideIndex()
  43. windll.user32.SetCursorPos(x, y)
  44. #参数1位x的起点 第二个参数是y的起点 这两个参数决定了起始的位置
  45. #参数3是x的终点位置 第四个参数是 y的终点位置
  46. self.app.SlideShowWindows(index).View.DrawLine(x, y, x + 500, y)
  47. def getActivePresentationSlideIndex(self):
  48. #得到活跃状态的PPT当前的页数
  49. if self.hasActivePresentation():
  50. try:
  51. index = self.app.ActiveWindow.View.Slide.SlideIndex
  52. except:
  53. index = self.app.SlideShowWindows(1).View.CurrentShowPosition
  54. return index
  55. def getActivePresentationSlideCount(self):
  56. #返回处于活跃状态的PPT的页面总数
  57. return self.app.ActivePresentation.Slides.Count
  58. def getPresentationCount(self):
  59. #返回打开的PPT数目
  60. return self.app.Presentations.Count
  61. def hasActivePresentation(self):
  62. #判断是否有打开PPT文件
  63. return True if self.getPresentationCount() > 0 else False
  64. if __name__ == '__main__':
  65. HOST = ''
  66. PORT = 5588
  67. BUFSIZE = 1024
  68. ADDR = (HOST, PORT)
  69. tcpSerSock = socket(AF_INET, SOCK_STREAM)
  70. tcpSerSock.bind(ADDR)
  71. tcpSerSock.listen(5)
  72. ppt = PowerPointControler()
  73. while True:
  74. print('waiting for connection...')
  75. tcpCliSock, addr = tcpSerSock.accept()
  76. print('...connected from:', addr)
  77. while True:
  78. data = tcpCliSock.recv(BUFSIZE).decode()
  79. print(data)
  80. if not data:
  81. break
  82. if ppt.hasActivePresentation():
  83. if data == "f5":
  84. ppt.fullScreen()
  85. elif data == "up":
  86. ppt.prePage()
  87. elif data == "down":
  88. ppt.nextPage()
  89. elif data == "left":
  90. ppt.prePage()
  91. elif data == "right":
  92. ppt.nextPage()
  93. elif data == "esc":
  94. ppt.closeFull()
  95. #else:未完成画线操作,只能话简单的直线
  96. #xy = data.split('#')
  97. #print(xy[0],xy[1])
  98. #ppt.drawLine(int(xy[0]), int(xy[1]))
  99. #xy.clear();
  100. else:
  101. tcpCliSock.send("close")
  102. tcpCliSock.close()
  103. tcpSerSock.close()

吾还年轻,写的代码比较烂,希望大家指正。 
项目下载地址:https://github.com/gqqcode/Mobile-phone-control-ppt

http://blog.csdn.net/guoqianqian5812/article/details/52627502

手机控制PPT good的更多相关文章

  1. 基于windowsphone7的控制ppt播放

    最近突然想起了一个学长的一个利用手机控制ppt播放的一个创意,并想将其在windows phone7上实现一下. 经过几天的努力已经可以控制ppt的播放,暂停,上一张,下一张了,并且电脑会将当前ppt ...

  2. nodePPT初认识启动与手机控制

    最近要做个PPT,想起之前看到过个网页PPT,于是这次就想尝试下,搜了下弹出个nodeppt---有可能是最好的网页PPT,那,就这个吧. 按照文档来,貌似有点问题,百度,又是一堆粘贴复制,没点用.自 ...

  3. 手机控制电脑,在WIFI局域网下(关机,重启,遥控)

    这个软件叫百变遥控:http://blog.sina.com.cn/s/blog_9abc7dbc0101hmut.html 今天周末,在家里看电影,家里用的是台式电脑,我自己买了一个投影仪来专门看视 ...

  4. 蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现

           蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现        尽管蓝牙4.0 BLE芯片CC2540 是单芯片(即用户能够对它进行芯片级代码编写), 是80 ...

  5. 手机控制电脑定时关机,重启WiFi

    需求 晚上上床,电脑开着WiFi让手机上网.要么上床之前就给电脑设置定时关机:要么就电脑开通宵:要么就待会下来关电脑.这3种情况都非常不好,要么麻烦,要么浪费. 最无奈的是电脑刚开好WiFi,上床后才 ...

  6. 我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(三)Android客户端功能实现

    我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(一)PC服务器端(地址:http://blog.csdn.net/ouyang_pen ...

  7. Kinect 开发 —— 控制PPT播放

    实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...

  8. Python 脚本利用adb 进行手机控制

    相关参考:https://www.cnblogs.com/bravesnail/articles/5850335.html 一.  adb 相关命令: 1. 关闭adb服务:adb kill-serv ...

  9. python:使用itchat实现手机控制电脑

    1.准备材料 首先电脑上需要安装了python,安装了opencv更好(非必需) 如果安装了opencv的话,在opencv的python目录下找到cv2.pyd,将该文件放到python的库搜索路径 ...

随机推荐

  1. erlang 符号相关基本语法

    http://blog.csdn.net/anghlq/article/details/6803332 ErLang语法约定: 大写字母开头的名字(比如Address),表示一个变量,包括参数.局部变 ...

  2. POJ 2104 - 主席树 / 询问莫队+权值分块

    传送门 题目大意应该都清楚. 今天看到一篇博客用分块+莫对做了这道题,直接惊呆了. 首先常规地离散化后将询问分块,对于某一询问,将莫队指针移动到指定区间,移动的同时处理权值分块的数字出现次数(单独.整 ...

  3. shell自动化下载、安装、配置nginx

    #!/bin/bash auto config nginx server #by author www.jfedu.net #2018年5月14日17:25:52 N_PAR="vim lr ...

  4. vultr的80端口?

    1.查看防火墙版本号firewall-cmd --version2.查看防火墙状态firewall-cmd --state3.添加80端口的权限firewall-cmd --zone=public - ...

  5. jquery.uploadify上传图片,点击保存按钮无法使用解决方法

    用Chrome浏览器上传商品图片时,保存按钮无法点击,如下图 原因:Flash插件状态为禁止 或 询问(默认) 解决方法:将Flash插件状态改为允许,如下图

  6. 获取web.config配置文件的sectionGroup

    1)web.config 文件内容如下: <configuration> <configSections> <sectionGroup name="KaiXin ...

  7. cordova打包之android应用签名

    原文:cordova打包之android应用签名 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/mate_ge/article/details/78 ...

  8. java server wrapper 和 maven assembly 插件

    Java Service Wrapper工具YAJSW 简介信息 YAJSW是一个开源的Java服务包装(Java Service Wrapper)工具.YAJSW允许您把任何应用程序安装为windo ...

  9. Matlab Tricks(十四) —— 句柄(handle)(图形对象属性的读取与修改)

    0. 句柄的获得 H = subplot(1,2,1); saveas(H, [pathname,filename], 'jpg'); 1. h = plot(-) a = 0:10:360; x = ...

  10. Java transient关键字【转】

    转自:http://www.blogjava.net/fhtdy2004/archive/2009/06/20/286112.htmlVolatile修饰的成员变量在每次被线程访问时,都强迫从主内存中 ...