2009-04-08 9 views
0

この問題に近づく方法が分からないので、GUIをPythonでTkinterを使って理想的に書いてみたいが、最初はQtで始まり、問題がすべてのGUIフレームワークまたは私の限られた理解のいずれかに及ぶことを発見しました。データが外部のソースから来たGUIにデータを表示

この場合のデータは名前付きパイプからのもので、パイプを通って来るものをテキストボックスに表示したいと思います。私は1つのスレッドがパイプでリッスンして、もう1つはGUIを作成しようとしましたが、どちらのスレッドでも常に1つのスレッドがハングしているようです。

提案がありますか?

+0

問題が発生しているコードの例を投稿できますか –

答えて

0

は、私は(Windowsの場合)、それを行うような方法である:

import wx, wx.lib.newevent, threading 
import win32event, win32pipe, win32file, pywintypes, winerror 


NewMessage, EVT_NEW_MESSAGE = wx.lib.newevent.NewEvent() 
class MessageNotifier(threading.Thread): 
    pipe_name = r"\\.\pipe\named_pipe_demo" 

    def __init__(self, frame): 
     threading.Thread.__init__(self) 
     self.frame = frame 

    def run(self): 
     open_mode = win32pipe.PIPE_ACCESS_DUPLEX | win32file.FILE_FLAG_OVERLAPPED 
     pipe_mode = win32pipe.PIPE_TYPE_MESSAGE 

     sa = pywintypes.SECURITY_ATTRIBUTES() 
     sa.SetSecurityDescriptorDacl(1, None, 0) 

     pipe_handle = win32pipe.CreateNamedPipe(
      self.pipe_name, open_mode, pipe_mode, 
      win32pipe.PIPE_UNLIMITED_INSTANCES, 
      0, 0, 6000, sa 
     ) 

     overlapped = pywintypes.OVERLAPPED() 
     overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None) 

     while 1: 
      try: 
       hr = win32pipe.ConnectNamedPipe(pipe_handle, overlapped) 
      except: 
       # Error connecting pipe 
       pipe_handle.Close() 
       break 

      if hr == winerror.ERROR_PIPE_CONNECTED: 
       # Client is fast, and already connected - signal event 
       win32event.SetEvent(overlapped.hEvent) 

      rc = win32event.WaitForSingleObject(
       overlapped.hEvent, win32event.INFINITE 
      ) 

      if rc == win32event.WAIT_OBJECT_0: 
       try: 
        hr, data = win32file.ReadFile(pipe_handle, 64) 
        win32file.WriteFile(pipe_handle, "ok") 
        win32pipe.DisconnectNamedPipe(pipe_handle) 
        wx.PostEvent(self.frame, NewMessage(data=data)) 
       except win32file.error: 
        continue 


class Messages(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None) 
     self.messages = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_READONLY) 
     self.Bind(EVT_NEW_MESSAGE, self.On_Update) 

    def On_Update(self, event): 
     self.messages.Value += "\n" + event.data 


app = wx.PySimpleApp() 
app.TopWindow = Messages() 
app.TopWindow.Show() 
MessageNotifier(app.TopWindow).start() 
app.MainLoop() 

テストはしていくつかのデータを送信することにより:

import win32pipe 

print win32pipe.CallNamedPipe(r"\\.\pipe\named_pipe_demo", "Hello", 64, 0) 

(あなたも、この場合の応答を取得)

0

私はこのようなことをしたときに、パイプでリスンする別のスレッドを使用しました。スレッドには、GUIに戻るポインタ/ハンドルがあり、表示するデータを送信することができます。

私はあなたがGUIの更新/イベントループでそれを行うことができると思いますが、パイプ上で非ブロック読み取りを行っていることを確認する必要があります。私は別のスレッドでそれをやりました。なぜなら、送られたデータに対して多くの処理を行う必要があったからです。

表示を行っているときは、一度に重要ではない「チャンク」で行ってください。更新コマンドをテキストボックスに送信しているメッセージキュー(Windowsでは少なくとも)を最大限に活用するのは非常に簡単です。

0

これまで、GUIの外部データ(例えば、イーサネットソケット)を読み込んでいたときに、外部のサービスの処理を行う別のスレッドと、時限付きのコールバックがありました半秒)、外部データを表示するGUIウィジェットを更新します。ここで

関連する問題