2011-11-17 28 views
5

Tôi đang cố viết một kịch bản Python đơn giản để giao tiếp với một máy chủ trò chuyện. Nó sẽ thăm dò ý kiến ​​của máy chủ để cập nhật và cho phép người dùng nhập văn bản để gửi tới máy chủ dưới dạng trò chuyện. Tôi có thể nhận được một cái gì đó bị tấn công cùng với đa luồng, nhưng có vẻ khủng khiếp. Có cách nào tốt đẹp, đơn giản để hiển thị thông tin cập nhật trên màn hình trong khi cũng chấp nhận đầu vào của người dùng? Tôi thích làm điều đó mà không có lời nguyền.Kịch bản Python tương tác không đồng bộ

+1

Để thực hiện hai tác vụ như vậy cùng một lúc, bạn cần chuỗi. Bạn cần phải có một thread để xử lý đầu vào của người dùng, có lẽ là chủ đề chính. Sau đó, tạo một chuỗi khác để xử lý các câu trả lời đến từ máy chủ trò chuyện. –

+0

Tôi nhận được phần đó hoạt động nhưng không hiển thị đúng. Tôi đã sử dụng raw_input để có được đầu vào, và nó bị rối tung lên khi bạn in ra văn bản sau khi nó được gọi. –

+2

@HunterMcMillen - không hoàn toàn đúng - một số khung công cụ giao diện người dùng và giao diện người dùng (G) sử dụng vòng lặp không phải luồng (thường dựa trên 'select'), ví dụ: PyGTK và Twisted. – detly

Trả lời

0

Cho phép cửa sổ/màn hình hiển thị được cung cấp bởi một db cục bộ tạm thời.

Mã 1: Cập nhật màn hình từ db. Bạn có thể sử dụng vòng lặp vô hạn có hoặc không có tạm dừng (tốc độ làm tươi màn hình)

Mã 2: cập nhật các db không sớm người dùng nhập vào một cái gì đó

Mã 3: Tiếp tục kiểm tra các bản cập nhật từ máy chủ trò chuyện và cập nhật db không sớm nhận được một resposes mới.

0

Tôi không biết cách viết mã bằng ncurses, nhưng đây là giải pháp với wxWidget. Nó sẽ gần như tương tự về thiết kế.

"""Asynchronous interactive Python script""" 
import random 
import threading 
import wx 
import wx.lib.mixins.listctrl as listmix 

LOCK = threading.Lock() 

def threadsafe(function): 
    """A decorator that makes a function safe against concurrent accesses.""" 
    def _decorated_function(*args, **kwargs): 
     """Replacement function.""" 
     with LOCK: 
      function(*args, **kwargs) 
    return _decorated_function 


class SharedList(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): 
    """An output list that can print information from both the user and the server. 

    N.B.: The _print function that actually updates the list content uses the threadsafe decorator. 
    """ 

    def __init__(self, parent, pos=wx.DefaultPosition, size=(-1, -1), style=wx.LC_REPORT): 
     wx.ListCtrl.__init__(self, parent, wx.ID_ANY, pos, size, style) 
     self.InsertColumn(0, 'Origin', width=75) 
     self.InsertColumn(1, 'Output') 
     listmix.ListCtrlAutoWidthMixin.__init__(self) 
     self.resizeLastColumn(1000) 
     self._list_index = 0 

    def user_print(self, text): 
     """Print a line as the user""" 
     self._print("user", text) 

    def chat_print(self, text): 
     """Print a line as the chat server""" 
     self._print("chat", text) 

    @threadsafe 
    def _print(self, origin, text): 
     """Generic print function.""" 
     self.InsertStringItem(self._list_index, str(origin)) 
     self.SetStringItem(self._list_index, 1, str(text)) 
     self.EnsureVisible(self.GetItemCount() - 1) 
     self._list_index = self._list_index + 1 


class ServerChecker(threading.Thread): 
    """A separate thread that would connect to the IRC chat.""" 

    def __init__(self, shared_list): 
     threading.Thread.__init__(self) 
     self._stop_event = threading.Event() 
     self._shared_list = shared_list 

    def run(self): 
     """Connection to the server, socket, listen, bla bla bla.""" 
     while not self._stop_event.is_set(): 
      self._shared_list.chat_print("bla bla bla") 
      self._stop_event.wait(random.randint(1, 3)) 

    def stop(self): 
     """Stop the thread.""" 
     self._stop_event.set() 


class SampleFrame(wx.Frame): 
    """The main GUI element.""" 

    def __init__(self): 
     super(SampleFrame, self).__init__(parent=None, title='DAS Board', size=(600, 400)) 
     self._shared_list = None 
     self._user_text = None 
     self._init_ui() 
     self._thread = ServerChecker(self._shared_list) 
     self._thread.start() 
     self.Bind(wx.EVT_CLOSE, self._on_close) 
     self.Center() 
     self.Show() 

    def _init_ui(self): 
     """Building and assembling the graphical elements. 
     Don't pay too much attention, especially if you want to use ncurses instead. 
     """ 
     panel = wx.Panel(self) 
     self._shared_list = SharedList(panel) 
     main_box_v = wx.BoxSizer(wx.VERTICAL) 
     main_box_v.Add(self._shared_list, proportion=1, flag=wx.EXPAND|wx.ALL, border=10) 
     self._user_text = wx.TextCtrl(panel, -1, value="User text to send...", 
             style=wx.TE_CENTRE) 
     main_box_v.Add(self._user_text, proportion=0, flag=wx.EXPAND|wx.ALL, border=10) 
     button = wx.Button(panel, label="Send user text.") 
     button.Bind(wx.EVT_BUTTON, self._user_send_text) 
     main_box_v.Add(button, flag=wx.EXPAND|wx.ALL, border=10) 
     panel.SetSizer(main_box_v) 

    def _user_send_text(self, event): 
     """Button callback""" 
     self._shared_list.user_print(self._user_text.GetValue()) 
     event.Skip() 

    def _on_close(self, event): 
     """Stop the separate thread, then destroy the GUI.""" 
     event.Skip() 
     self._thread.stop() 
     self.Destroy() 


APP = wx.App(0) 
SampleFrame() 
APP.MainLoop() 
Các vấn đề liên quan