手机控制PPT good
以前做了一个小东西,通过手机来控制PPT的翻页,最大化和最小化,东西很简单,近期整理电脑发现了拿来和大家分享一下
主要分为两个部分,客户端和服务器
客户端实现
当初考虑到跨平台的特性就选择了qt来写的,代码很简单,主要是通过socket连接运行在电脑上的server,发送不同的指令完成不同的操作。由于Qt的跨平台性可以将其移植到安卓和iOS上,安卓上使用完全没问题,ios也应该是没问题,我不是土豪,没法用苹果手机测试,有兴趣的大家可以试试
Control_PPT.pro
#-------------------------------------------------
#
# Project created by QtCreator 2016-06-20T09:20:20
#
#-------------------------------------------------
QT += core gui
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Control_PPT
TEMPLATE = app
SOURCES += main.cpp\
mainwidget.cpp
HEADERS += mainwidget.h
mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
#include <QtNetwork/QtNetwork>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QMessageBox>
#include <QMouseEvent>
#include <QStatusBar>
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = 0);
~MainWidget();
void initIpLayout();
void initControlBtnLayout();
// void mouseMoveEvent(QMouseEvent *event);
private:
QLabel *ipLbl;
QLineEdit *ipLineEdit;
QPushButton *connectBtn;
/*
控制按钮 上一页、写一页等
*/
QPushButton *upBtn;
QPushButton *downBtn;
QPushButton *leftBtn;
QPushButton *rightBtn;
QPushButton *f5Btn;
QPushButton *escBtn;
/*
布局
*/
QHBoxLayout *ipHLayout;
QGridLayout *controlBtnLayout;
QVBoxLayout *mainVLayout;
QTcpSocket *client;
QStatusBar *statusBar;
QLabel *msgLabel;
bool flag;
public slots:
void conncSlot();
void upSlot();
void downSlot();
void leftSlot();
void rightSlot();
void f5Slot();
void escSlot();
void displayError(QAbstractSocket::SocketError);
};
#endif // MAINWIDGET_H
main.widget.cpp
#include "mainwidget.h"
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
flag = true;
msgLabel = new QLabel;
//msgLabel->setMinimumSize(msgLabel->sizeHint());
msgLabel->setAlignment(Qt::AlignHCenter);
statusBar = new QStatusBar(this);
statusBar->setFixedHeight(30);
statusBar->setFixedWidth(this->width());
statusBar->addWidget(msgLabel); //头文件要添加include<QStatusBar>才不会报错
initIpLayout();
initControlBtnLayout();
mainVLayout = new QVBoxLayout;
mainVLayout->addLayout(ipHLayout);
mainVLayout->addLayout(controlBtnLayout);
this->setLayout(mainVLayout);
connect(connectBtn,SIGNAL(clicked()),this, SLOT(conncSlot()));
connect(upBtn,SIGNAL(clicked()),this, SLOT(upSlot()));
connect(downBtn,SIGNAL(clicked()),this, SLOT(downSlot()));
connect(f5Btn,SIGNAL(clicked()),this, SLOT(f5Slot()));
connect(leftBtn,SIGNAL(clicked()),this, SLOT(leftSlot()));
connect(rightBtn,SIGNAL(clicked()),this, SLOT(rightSlot()));
connect(escBtn,SIGNAL(clicked()),this, SLOT(escSlot()));
}
/*
设置获取ip连接的布局
*/
void MainWidget::initIpLayout()
{
ipLbl = new QLabel(tr("IP:"));
ipLineEdit = new QLineEdit();
ipLineEdit->setPlaceholderText(tr("127.0.0.1"));
connectBtn = new QPushButton(tr("连接"));
ipHLayout = new QHBoxLayout;
ipHLayout->addWidget(ipLbl);
ipHLayout->addWidget(ipLineEdit);
ipHLayout->addWidget(connectBtn);
// ipHLayout->setMargin(10);
}
void MainWidget::initControlBtnLayout()
{
upBtn = new QPushButton(tr("上"));
leftBtn = new QPushButton(tr("左"));
f5Btn = new QPushButton(tr("f5"));
rightBtn = new QPushButton(tr("右"));
downBtn = new QPushButton(tr("下"));
escBtn = new QPushButton(tr("esc"));
controlBtnLayout = new QGridLayout();
controlBtnLayout->addWidget(upBtn,0,1);
controlBtnLayout->addWidget(leftBtn, 1, 0);
controlBtnLayout->addWidget(f5Btn,1,1);
controlBtnLayout->addWidget(rightBtn, 1, 2);
controlBtnLayout->addWidget(downBtn, 2, 1);
controlBtnLayout->addWidget(escBtn, 3, 1);
}
//void MainWidget::mouseMoveEvent(QMouseEvent *event)
//{
// int x = event->x();
// int y = event->y();
// QPoint point = cursor().pos();
// int x = point.x();
// int y = point.y();
// QString xy;
// xy.clear();
// xy = tr("%1%2%3").arg(x).arg("#").arg(y);
// qDebug() << xy;
// char* chxy;
// QByteArray ba = xy.toLatin1();
// chxy=ba.data();
// if(flag)
// client->write(chxy);
//}
void MainWidget::displayError(QAbstractSocket::SocketError)
{
flag = false;
qDebug() << client->errorString(); //输出错误信息
}
void MainWidget::conncSlot()
{
QString ip = ipLineEdit->text();
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])$");
QRegExp rx(pattern);
if(ip.isEmpty())
{
QMessageBox::information(this,"请输入IP","请输入服务器的IP地址!");
return ;
}
else if(!(rx.exactMatch(ip)))
{
QMessageBox::information(this,"格式错误","请输入正确的IP地址!");
return ;
}
client = new QTcpSocket(this);
client->connectToHost(QHostAddress(ip), 5588);
//connect(client, SIGNAL(connected()),this, SLOT(is_connect_ok()));
connect(client,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError)));
if(flag)
{
msgLabel->setText(tr("连接成功!"));
QMessageBox::information(this,tr("连接提示"),tr("恭喜你连接成功"));
flag = false;
}
else
{
msgLabel->setText(tr("连接失败!"));
QMessageBox::information(this,tr("连接提示"),tr("连接失败,请检查ip是否正确"));
}
ipLineEdit->clear();
}
void MainWidget::escSlot()
{
client->write("esc");
msgLabel->setText(tr("退出全屏显示"));
//client->write("100#100");
}
void MainWidget::upSlot()
{
client->write("up");
msgLabel->setText(tr("上一页!"));
}
void MainWidget::downSlot()
{
msgLabel->setText(tr("下一页!"));
client->write("down");
}
void MainWidget::leftSlot()
{
msgLabel->setText(tr("上一页!"));
client->write("left");
}
void MainWidget::rightSlot()
{
msgLabel->setText(tr("下一页!"));
client->write("right");
}
void MainWidget::f5Slot()
{
msgLabel->setText(tr("全屏显示!"));
client->write("f5");
}
MainWidget::~MainWidget()
{
}
main.cpp
#include "mainwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWidget w;
w.show();
return a.exec();
}
服务器端
服务器端是Python写的,当然用c++也是可以的,考虑到代码的简洁就选择了python,正好当时刚学了几点的python就用了它,代码写的很烂。服务器的作用主要是调用微软提供的PPT接口完成操作。
server.py
# Echo server program
from socket import*
from time import ctime
import win32com.client
import win32api
import win32con
import time
import pythoncom
from ctypes import *
class PowerPointControler:
def __init__(self):
pythoncom.CoInitialize()
self.app = win32com.client.Dispatch("PowerPoint.Application")
def fullScreen(self):
#全屏播放
if self.hasActivePresentation():
#使用Run方法创建一个新的幻灯片放映窗口并将其添加到SlideShowWindows集合
self.app.ActivePresentation.SlideShowSettings.Run()#该方法用于运行指定演示文稿的幻灯片放映。
return self.getActivePresentationSlideIndex()
def closeFull(self):#结束第一个幻灯片放映窗口中的幻灯片放映
if self.app.ActivePresentation.SlideShowSettings.Run():
self.app.SlideShowWindows(1).View.Exit()
def gotoSlide(self,index):
#跳转到指定的页面
if self.hasActivePresentation():
try:
self.app.ActiveWindow.View.GotoSlide(index)
return self.app.ActiveWindow.View.Slide.SlideIndex
except:
self.app.SlideShowWindows(1).View.GotoSlide(index)
return self.app.SlideShowWindows(1).View.CurrentShowPosition
def nextPage(self):#下一页ppt
if self.hasActivePresentation():
count = self.getActivePresentationSlideCount()
index = self.getActivePresentationSlideIndex()
return count if index >= count else self.gotoSlide(index+1)
def prePage(self):#上一页ppt
if self.hasActivePresentation():
index = self.getActivePresentationSlideIndex()
return index if index <= 1 else self.gotoSlide(index-1)
def drawLine(self, x, y):
index = self.getActivePresentationSlideIndex()
windll.user32.SetCursorPos(x, y)
#参数1位x的起点 第二个参数是y的起点 这两个参数决定了起始的位置
#参数3是x的终点位置 第四个参数是 y的终点位置
self.app.SlideShowWindows(index).View.DrawLine(x, y, x + 500, y)
def getActivePresentationSlideIndex(self):
#得到活跃状态的PPT当前的页数
if self.hasActivePresentation():
try:
index = self.app.ActiveWindow.View.Slide.SlideIndex
except:
index = self.app.SlideShowWindows(1).View.CurrentShowPosition
return index
def getActivePresentationSlideCount(self):
#返回处于活跃状态的PPT的页面总数
return self.app.ActivePresentation.Slides.Count
def getPresentationCount(self):
#返回打开的PPT数目
return self.app.Presentations.Count
def hasActivePresentation(self):
#判断是否有打开PPT文件
return True if self.getPresentationCount() > 0 else False
if __name__ == '__main__':
HOST = ''
PORT = 5588
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
ppt = PowerPointControler()
while True:
print('waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept()
print('...connected from:', addr)
while True:
data = tcpCliSock.recv(BUFSIZE).decode()
print(data)
if not data:
break
if ppt.hasActivePresentation():
if data == "f5":
ppt.fullScreen()
elif data == "up":
ppt.prePage()
elif data == "down":
ppt.nextPage()
elif data == "left":
ppt.prePage()
elif data == "right":
ppt.nextPage()
elif data == "esc":
ppt.closeFull()
#else:未完成画线操作,只能话简单的直线
#xy = data.split('#')
#print(xy[0],xy[1])
#ppt.drawLine(int(xy[0]), int(xy[1]))
#xy.clear();
else:
tcpCliSock.send("close")
tcpCliSock.close()
tcpSerSock.close()
吾还年轻,写的代码比较烂,希望大家指正。
项目下载地址:https://github.com/gqqcode/Mobile-phone-control-ppt
http://blog.csdn.net/guoqianqian5812/article/details/52627502
手机控制PPT good的更多相关文章
- 基于windowsphone7的控制ppt播放
最近突然想起了一个学长的一个利用手机控制ppt播放的一个创意,并想将其在windows phone7上实现一下. 经过几天的努力已经可以控制ppt的播放,暂停,上一张,下一张了,并且电脑会将当前ppt ...
- nodePPT初认识启动与手机控制
最近要做个PPT,想起之前看到过个网页PPT,于是这次就想尝试下,搜了下弹出个nodeppt---有可能是最好的网页PPT,那,就这个吧. 按照文档来,貌似有点问题,百度,又是一堆粘贴复制,没点用.自 ...
- 手机控制电脑,在WIFI局域网下(关机,重启,遥控)
这个软件叫百变遥控:http://blog.sina.com.cn/s/blog_9abc7dbc0101hmut.html 今天周末,在家里看电影,家里用的是台式电脑,我自己买了一个投影仪来专门看视 ...
- 蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现
蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现 尽管蓝牙4.0 BLE芯片CC2540 是单芯片(即用户能够对它进行芯片级代码编写), 是80 ...
- 手机控制电脑定时关机,重启WiFi
需求 晚上上床,电脑开着WiFi让手机上网.要么上床之前就给电脑设置定时关机:要么就电脑开通宵:要么就待会下来关电脑.这3种情况都非常不好,要么麻烦,要么浪费. 最无奈的是电脑刚开好WiFi,上床后才 ...
- 我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(三)Android客户端功能实现
我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(一)PC服务器端(地址:http://blog.csdn.net/ouyang_pen ...
- Kinect 开发 —— 控制PPT播放
实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...
- Python 脚本利用adb 进行手机控制
相关参考:https://www.cnblogs.com/bravesnail/articles/5850335.html 一. adb 相关命令: 1. 关闭adb服务:adb kill-serv ...
- python:使用itchat实现手机控制电脑
1.准备材料 首先电脑上需要安装了python,安装了opencv更好(非必需) 如果安装了opencv的话,在opencv的python目录下找到cv2.pyd,将该文件放到python的库搜索路径 ...
随机推荐
- python request get
import requests from urllib import parse # 返回response resp = requests.get("https://www.baidu.co ...
- git merge与rebase
参考这篇文章 Git 之 merge 与 rebase 的区别 文章2 另外,使 rebase出现冲突后,先修改冲突,然后git add 某文件(我使用add .经常有问题),然后git reba ...
- 全文检索(elasticsearch入门)
Elasticsearch篇: Elasticsearch是一个采用java语言开发的,基于Lucene构造的开源,分布式的搜索引擎. 设计用于云计算中,能够达到实时搜索,稳定可靠. Elastics ...
- WPF 从程序集中检索图片资源stream给Image控件使用
原文:WPF 从程序集中检索图片资源stream给Image控件使用 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/nihang1234/artic ...
- Win7 32bit下一个hadoop2.5.1源代码编译平台的搭建各种错误遇到
从小白在安装hadoop困难和错误时遇到说起,同时,我们也希望能得到上帝的指示. 首先hadoop更新速度非常快,最新的是hadoop2.5.1,因此就介绍下在安装2.5.1时遇到的各种困难. 假设直 ...
- git clone命令简介
git clone: 正如上图,当我们打开终端的情况下,默认我们所在的目录是在/home/shiyanlou的,大家可以在终端输入以下命令把目录切换到桌面cd /home/Desktop这个时候输入 ...
- 【C语言学习】C语言功能
代码,功能为了更好地实现模块化编程.那么,什么是函数的性质?在函数中定义的变量(全局变量.局部变量.静态变量)如何存储?为什么范围和全局变量和局部变量的寿命是不一样的?只是有一个更深入的了解的功能.能 ...
- Linux 下编译并安装配置 Qt 4.53全过程
最近准备做 Nokia 的 Symbian,Maemo 下触摸屏开发.考虑到程序的跨平台可移植性,最终选择使用 Qt 开发.相对来说,国内关于 Qt 相关文档并不算很多.作者将 Linux 下编译并安 ...
- 【winows7+android-ndk-r9+Cygwin 】cocos2dx 2.*游戏移植Android平台完全手册
为了有不少走的弯路.这里简要记录cocos2d开发环境的搭建.android开发环境搭建.android NDK环境搭建.终于实现cocos2dx 2.* 游戏Android平台移植. 转载请注明出处 ...
- AWS核心服务概览
1.Amazon Web Service 应该可以说,Amazon Web Service目前是云计算领域的领头羊,其业务规模.开发水平和盈利能力在业界内都是首屈一指的.从本科毕业离开学校就一直做Ja ...