以前做了一个小东西,通过手机来控制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
时间: 2024-10-13 16:23:25