Abh*_*tia 5 python sockets canvas kivy
主文件
from kivy.base import EventLoop
from kivy.config import Config
from kivy.graphics import Color, Line
from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.widget import Widget
from kivy.utils import get_color_from_hex
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.clock import Clock
CURSOR = (
' @@@@ ',
' @--@ ',
' @--@ ',
' @--@ ',
' @--@ ',
' @@@@ ',
' ',
'@@@@@@ @@@@ @@@@@@ ',
'@----@ @--@ @----@ ',
'@----@ @--@ @----@ ',
'@@@@@@ @@@@ @@@@@@ ',
' ',
' @@@@ ',
' @--@ ',
' @--@ ',
' @--@ ',
' @--@ ',
' @@@@ ',
' ',
' ',
' ',
' ',
' ',
' ',
)
class Update_Location(Widget):
pass
class CanvasWidget(Widget):
line_width = 2
def on_touch_down(self, touch):
if Widget.on_touch_down(self, touch):
return
with self.canvas:
touch.ud['current_line'] = Line(
points=(touch.x, touch.y),
width=self.line_width)
def on_touch_move(self, touch):
if 'current_line' in touch.ud:
touch.ud['current_line'].points += (touch.x, touch.y)
def set_color(self, new_color):
self.last_color = new_color
self.canvas.add(Color(*new_color))
def set_line_width(self, line_width='Normal'):
self.line_width = {
'Thin': 1, 'Normal': 2, 'Thick': 4
}[line_width]
def clear_canvas(self):
saved = self.children[:]
self.clear_widgets()
self.canvas.clear()
for widget in saved:
self.add_widget(widget)
self.set_color(self.last_color)
def start_server(self):
host = '127.0.0.1'
port = 5000
notification_text="Server started on host: "+host+" and port: "+str(port)
server_start=Popup(title='Notification',content=Label(text=notification_text),size_hint=(.75,.75),auto_dismiss=True)
server_start.open()
Clock.schedule_interval(server_start.dismiss, 3)
class PaintApp(App):
def build(self):
EventLoop.ensure_window()
if EventLoop.window.__class__.__name__.endswith('Pygame'):
try:
from pygame import mouse
a, b = pygame_compile_cursor()
mouse.set_cursor((24, 24), (9, 9), a, b)
except:
pass
#boxlayout
self.layout = BoxLayout(orientation='vertical')
self.canvas_widget = CanvasWidget()
self.canvas_widget.set_color(
get_color_from_hex('#2980b9'))
self.layout.add_widget(self.canvas_widget)
#self.layout.add_widget(Label(text="Started Server : False , Connected to Server : False",color=(1,1,1),size_hint=(1, .1)))
return self.layout
#return self.canvas_widget
class RadioButton(ToggleButton):
def _do_press(self):
if self.state == 'normal':
ToggleButtonBehavior._do_press(self)
def pygame_compile_cursor(black='@', white='-'):
aa, bb = [], []
a = b = 0
i = 8
for s in CURSOR:
for c in s:
a <<= 1
b <<= 1
i -= 1
if c == black:
a |= 1
b |= 1
elif c == white:
b |= 1
if not i:
aa.append(a)
bb.append(b)
a = b = 0
i = 8
return tuple(aa), tuple(bb)
if __name__ == '__main__':
Config.set('graphics', 'width', '960')
Config.set('graphics', 'height', '540') # 16:9
# Config.set('graphics', 'resizable', '0')
# Config.set('input', 'mouse', 'mouse,disable_multitouch')
from kivy.core.window import Window
Window.clearcolor = get_color_from_hex('#ffffff')
PaintApp().run()
Run Code Online (Sandbox Code Playgroud)
服务器.py
import socket
def start_server(host,port):
s = socket.socket()
s.bind((host,port))
s.listen(1)
c, addr = s.accept()
print "Connection from: " + str(addr)
while True:
data = c.recv(1024)
if not data:
break
print "from connected user: " + str(data)
data = str(data).upper()
print "sending: " + str(data)
c.send(data)
c.close()
if __name__ == '__main__':
start_server()
Run Code Online (Sandbox Code Playgroud)
以上是我的简单油漆应用程序的代码(从 kivy blue prints 中采用)。
我的目标是在本地主机上的一个应用程序上启动服务器,然后其他应用程序连接到它。那些可以连接到它的人应该从他们连接的服务器上更新他们的画布。如何发送数据并更新画布。我在上面的代码中使用 python 的套接字库创建了一个服务器。
我不想使用 http 请求/线程而是建立与套接字的连接并使用 async.io。
小智 4
我创建了一个快速的 REST Flask 服务,其中包含支持 post 的 /canvas 端点。我还创建了 CanvasWidget 类的lines成员来保存如何重新创建数据以将其发送到服务器。我曾考虑过逐像素进行,但我认为跟踪线条创建更优雅,并且如果需要的话,将支持撤消重做功能。
路线
主要.py
from kivy.app import App
from kivy.base import EventLoop
from kivy.config import Config
from kivy.graphics import Color, Line
from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.widget import Widget
from kivy.utils import get_color_from_hex
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.clock import Clock
from kivy.network.urlrequest import UrlRequest
import flask
CURSOR = (
' @@@@ ',
' @--@ ',
' @--@ ',
' @--@ ',
' @--@ ',
' @@@@ ',
' ',
'@@@@@@ @@@@ @@@@@@ ',
'@----@ @--@ @----@ ',
'@----@ @--@ @----@ ',
'@@@@@@ @@@@ @@@@@@ ',
' ',
' @@@@ ',
' @--@ ',
' @--@ ',
' @--@ ',
' @--@ ',
' @@@@ ',
' ',
' ',
' ',
' ',
' ',
' ',
)
class Update_Location(Widget):
pass
class CanvasWidget(Widget):
line_width = 2
lines = []
def __init__(self, **kwargs):
super(CanvasWidget, self).__init__(**kwargs)
self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
self._keyboard.bind(on_key_down=self._on_keyboard_down)
def _keyboard_closed(self):
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
if keycode[1] == 's':
print 'send'
json = flask.json.dumps(self.lines)
req = UrlRequest('http://127.0.0.1:5000/canvas', req_body=json)
elif keycode[1] == 'r':
print 'receive'
req = UrlRequest('http://127.0.0.1:5000/canvas', self.load_state)
def on_touch_down(self, touch):
if Widget.on_touch_down(self, touch):
return
with self.canvas:
touch.ud['current_line'] = Line(
points=(touch.x, touch.y),
width=self.line_width)
self.lines.append({'points':[touch.x,touch.y], 'width':self.line_width})
def on_touch_move(self, touch):
if 'current_line' in touch.ud:
touch.ud['current_line'].points += (touch.x, touch.y)
self.lines[-1]['points'].append(touch.x)
self.lines[-1]['points'].append(touch.y)
def set_color(self, new_color):
self.last_color = new_color
self.canvas.add(Color(*new_color))
def set_line_width(self, line_width='Normal'):
self.line_width = {
'Thin': 1, 'Normal': 2, 'Thick': 4
}[line_width]
def clear_canvas(self):
saved = self.children[:]
self.clear_widgets()
self.canvas.clear()
for widget in saved:
self.add_widget(widget)
self.set_color(self.last_color)
def load_state(self, req, results):
print 'load_state req', repr(req)
print 'load_state results', repr(results)
#needs some validation here
self.clear_canvas()
with self.canvas:
for line in results:
Line(points=line['points'], width=line['width'])
self.line = results
def start_server(self):
host = '127.0.0.1'
port = 5000
notification_text="Server started on host: "+host+" and port: "+str(port)
server_start=Popup(title='Notification',content=Label(text=notification_text),size_hint=(.75,.75),auto_dismiss=True)
server_start.open()
Clock.schedule_interval(server_start.dismiss, 3)
class PaintApp(App):
def build(self):
EventLoop.ensure_window()
if EventLoop.window.__class__.__name__.endswith('Pygame'):
try:
from pygame import mouse
a, b = pygame_compile_cursor()
mouse.set_cursor((24, 24), (9, 9), a, b)
except:
pass
#boxlayout
self.layout = BoxLayout(orientation='vertical')
self.canvas_widget = CanvasWidget()
self.canvas_widget.set_color(
get_color_from_hex('#2980b9'))
self.layout.add_widget(self.canvas_widget)
#self.layout.add_widget(Label(text="Started Server : False , Connected to Server : False",color=(1,1,1),size_hint=(1, .1)))
return self.layout
#return self.canvas_widget
class RadioButton(ToggleButton):
def _do_press(self):
if self.state == 'normal':
ToggleButtonBehavior._do_press(self)
def pygame_compile_cursor(black='@', white='-'):
aa, bb = [], []
a = b = 0
i = 8
for s in CURSOR:
for c in s:
a <<= 1
b <<= 1
i -= 1
if c == black:
a |= 1
b |= 1
elif c == white:
b |= 1
if not i:
aa.append(a)
bb.append(b)
a = b = 0
i = 8
return tuple(aa), tuple(bb)
if __name__ == '__main__':
Config.set('graphics', 'width', '960')
Config.set('graphics', 'height', '540') # 16:9
# Config.set('graphics', 'resizable', '0')
# Config.set('input', 'mouse', 'mouse,disable_multitouch')
from kivy.core.window import Window
Window.clearcolor = get_color_from_hex('#ffffff')
PaintApp().run()
Run Code Online (Sandbox Code Playgroud)
服务器.py
from flask import Flask, jsonify, request, json
app = Flask(__name__)
data = []
@app.route('/canvas', methods = ['GET', 'POST'])
def canvas():
global data
if request.method == 'GET':
tmp = jsonify({})
tmp.set_data(json.dumps(data))
return tmp
if request.method == 'POST':
data = json.loads(request.data)
tmp = jsonify({})
tmp.set_data(json.dumps(data))
return tmp
if __name__ == '__main__':
app.run(debug=True)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
446 次 |
| 最近记录: |