2017-02-17 11 views
0

遠く離れたコンピュータのスクリーンショットをwx Pythonを使ってGUIパネルに表示する必要があります。さらに、私は0.04秒ごとにスクリーンショットを新しいスクリーンショットに置き換える必要があります。私はこのためにスレッドを使用しています。この問題は、コードが最後のスクリーンショット(プログラムを停止したとき)以外のイメージを表示しないときに始まります。私の質問は、同じプラットフォームでスクリーンショットを表示し、0.04秒ごとに画像を変更するように、コード内で変更する必要があることです。私は私のサーバー側(遠方にあるコンピュータからスクリーンショットを送信する)とクライアント側(自分のコンピュータ)のコードを追加します。 クライアント側: 輸入WX 輸入ソケットwxPythonを使用してjpgイメージを表示し、x秒ごとに同じパネルで変更するにはどうすればいいですか?

import threading 
import time 
import cStringIO 


PORT = 1729 
IP = '127.0.0.1' 
LOCATION = 'C:\stam\stam1.jpg' 
class PhotoCtrl(wx.App): 
    def __init__(self, redirect=False, filename=None): 
     wx.App.__init__(self, redirect, filename) 
     self.frame = wx.Frame(None, title='Photo Control') 

     self.panel = wx.Panel(self.frame) 

     self.PhotoMaxSize = 240 




def createWidgets(self): 
    imageFile = LOCATION 
    data = open(imageFile, "rb").read() 
    stream = cStringIO.StringIO(data) 
    self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY, wx.BitmapFromImage(wx.ImageFromStream(stream))) 
    self.mainSizer = wx.BoxSizer(wx.VERTICAL) 
    self.sizer = wx.BoxSizer(wx.HORIZONTAL) 
    self.mainSizer.Add(wx.StaticLine(self.panel, wx.ID_ANY), 0, wx.ALL|wx.EXPAND, 5) 
    self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5) 
    self.panel.SetSizer(self.mainSizer) 
    self.mainSizer.Fit(self.frame) 
    self.panel.Layout() 
    self.panel.Center() 
    self.frame.Show() 



class User(wx.Frame): 

def __init__(self, parent, id): 
    wx.Frame.__init__(self, parent, id, 'MiniViewer2017', size=(500, 500)) 
    panel = wx.Panel(self) 
    button_scan = wx.Button(panel, label='start scanning!') 
    button_exit = wx.Button(panel, label='exit', pos=(400, 300)) 
    self.Bind(wx.EVT_BUTTON, self.Scan, button_scan) 

    self.Bind(wx.EVT_BUTTON, self.closebutton, button_exit) 
    self.Bind(wx.EVT_CLOSE, self.closewindow) 

def Scan(self, event): 

    client_socket = self.connetet_socket('127.0.0.1', PORT) 

    app = PhotoCtrl() 
    t1 = threading.Thread(target=self.ScreenThread(client_socket, app)) 
    t1.start() 
    app.MainLoop() 

def recieve_all(self, client_socket): 
    """ input:socket output: the data we recieved from the server""" 
    str_length = int(client_socket.recv(1024)) 
    new_data = client_socket.recv(str_length) 
    return new_data 

def connetet_socket(self, ip, port): 
    """ input : ip and port output : socket """ 
    try: 
     client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     client_socket.connect((ip, port)) 
    except socket.error as msg: 
     print msg 
     client_socket = None 
    return client_socket 


def ask_for_screen_shot(self, client_socket,app): 
    client_socket.send("Send me your screen") 
    time.sleep(0.0001) 
    screen_shot = self.recieve_all(client_socket) 
    print "i got it" 
    f = open(LOCATION, 'wb') 
    f.write(screen_shot) 
    f.close() 
    app.createWidgets() 

def ScreenThread(self, client_socket,app): 
    fl=True 
    while fl: 
     self.ask_for_screen_shot(client_socket,app) 
     time.sleep(0.04) 
def closebutton(self,event): 
    self.Close(True) 

def closewindow(self, event): 
    self.Destroy() 


def main(): 
    app = wx.PySimpleApp() 
    frame = User(parent=None, id=-1) 
    frame.Show() 
    app.MainLoop() 



if __name__ == '__main__': 
    main() 

サーバ側:

import ImageGrab, socket, threading 
PORT = 1729 
def print_screen(): 
    im = ImageGrab.grab() 
    im.save('C:\stam\stam.jpg') #!!!before starting, make sure you have a  folder in C drive named "stam"!!! 
    with open('C:\stam\stam.jpg', 'rb') as f: 
     return f.read() 

def create_server_socket(ip, PORT): 
    """ input : ip and port output : server_socket """ 
    try: 
     server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     server_socket.bind((ip, PORT)) 
     server_socket.listen(1) 
    except socket.error as msg: 
     server_socket.close() 
     server_socket = None 
     print msg 
    return server_socket 


def send_message(client_socket, msg): 
    #the function sends the client the length of the message(screen shot), and then send the screen shot while the client already set the amount of bits he is about to get. 
    try: 
     str_msg = str(msg) 
     str_msg_length = len(str_msg) 
     client_socket.send(str(str_msg_length)) 
     client_socket.send(msg) 
    except socket.error as msg: 
     client_socket.close() 
     print msg 

def ScreenThread(client_socket): 

    while True: 
     r = client_socket.recv(50) 
     print r 
     if r == "Send me your screen": 
      send_message(client_socket, print_screen()) 
      print "The image has been sent successfully!" 
     else: 
      pass 
def main(): 

    while True: 
     server_socket_screen = create_server_socket('0.0.0.0', PORT) 

     if server_socket_screen is not None: 
      client_socket, address = server_socket_screen.accept() 

      t1 = threading.Thread(target=ScreenThread(client_socket)) 
      t1.start() 



if __name__ == '__main__': 
    main() 
+0

なぜ新しいイメージごとにウィジェットを再作成していますか? – user2682863

+0

私はwx Pythonで新しく、同じパネル上でイメージを変更する方法はわかりません。 –

答えて

0

あなたはその基本的な概念を理解することができますので、私はwxPythonのチュートリアルで始まるをお勧めします。 See Here

ピクチャコントロールをwx.Appの代わりにフレームを継承するように変更しました。いくつかの変更点を説明するためにコード全体にいくつかのコメントを追加しました。

「ユーザー」フレームと画像制御フレームの2つのフレームがあります。ユーザフレームはスレッドを実行し、画像制御フレーム上の画像を更新する。

import cStringIO 
import wx 
import os 
import threading 
import socket 
import time 

PORT = 1729 
IP = '127.0.0.1' 
LOCATION = 'C:\stam\stam1.jpg' 


class PhotoCtrl(wx.Frame): 
    def __init__(self, parent): 
     wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition, 
          size=wx.Size(500, 300), style=wx.DEFAULT_FRAME_STYLE) 

     self.panel = wx.Panel(self.frame) 

     self.PhotoMaxSize = 240 
     self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY, wx.EmptyBitmap()) 
     self.mainSizer = wx.BoxSizer(wx.VERTICAL) 
     self.sizer = wx.BoxSizer(wx.HORIZONTAL) 
     self.mainSizer.Add(wx.StaticLine(self.panel, wx.ID_ANY), 0, wx.ALL | wx.EXPAND, 5) 
     self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5) 
     self.panel.SetSizer(self.mainSizer) 
     self.mainSizer.Fit(self.frame) 
     self.panel.Layout() 
     self.panel.Center() 

     self.frame.Show() 

    def update_image(self): 
     imageFile = LOCATION 
     if not os.path.exists(imageFile): 
      return 

     with open(imageFile, "rb") as fileobj: 
      data = fileobj.read() 
     stream = cStringIO.StringIO(data) 
     bmp = wx.BitmapFromImage(wx.ImageFromStream(stream)) 
     self.imageCtrl.SetBitmap(bmp) 


class User(wx.Frame): 
    def __init__(self, parent, id): 
     wx.Frame.__init__(self, parent, id, 'MiniViewer2017', size=(500, 500)) 
     panel = wx.Panel(self) 
     button_scan = wx.Button(panel, label='start scanning!') 
     button_exit = wx.Button(panel, label='exit', pos=(400, 300)) 
     self.Bind(wx.EVT_BUTTON, self.Scan, button_scan) 

     self.Bind(wx.EVT_BUTTON, self.closebutton, button_exit) 
     self.Bind(wx.EVT_CLOSE, self.closewindow) 

     # create the photo ctrl as a child frame 
     self.photo_ctrl = PhotoCtrl(self) 

    def Scan(self, event): 

     client_socket = self.connetet_socket('127.0.0.1', PORT) 

     # app = PhotoCtrl() 
     t1 = threading.Thread(target=self.ScreenThread(client_socket, app)) 
     t1.start() 
     app.MainLoop() 

    def recieve_all(self, client_socket): 
     """ input:socket output: the data we recieved from the server""" 
     str_length = int(client_socket.recv(1024)) 
     new_data = client_socket.recv(str_length) 
     return new_data 

    def connetet_socket(self, ip, port): 
     """ input : ip and port output : socket """ 
     try: 
      client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
      client_socket.connect((ip, port)) 
     except socket.error as msg: 
      print msg 
      client_socket = None 
     return client_socket 

    def ask_for_screen_shot(self, client_socket, app): 
     client_socket.send("Send me your screen") 
     time.sleep(0.0001) 
     screen_shot = self.recieve_all(client_socket) 
     print "i got it" 
     with open(LOCATION, "wb") as fileobj: 
      fileobj.write(screen_shot) # you could probably just pass the data directly to update_image instead of writing to a file 
     self.photo_ctrl.update_image() 

    def ScreenThread(self, client_socket, app): 
     fl = True 
     while fl: 
      self.ask_for_screen_shot(client_socket, app) 
      time.sleep(0.04) 

    def closebutton(self, event): 
     self.Close(True) 

    def closewindow(self, event): 
     self.Destroy() # when Frames are deleted they automatically call destroy 


app = wx.App() 
user = User(None, -1) 
user.Show() 
app.MainLoop() 
+0

すごいよ!そんなにありがとう、あなたは私をたくさん助けました! –

関連する問題