在GUI中显示数据来自外部源的数据

时间:2009-04-08 20:46:51

标签: python user-interface named-pipes

我对如何处理这个问题感到很遗憾,我想在理想情况下使用Tkinter和python编写一个GUI,但我最初从Qt开始,发现问题扩展到所有GUI框架或我的有限理解。

这种情况下的数据来自命名管道,我想通过管道显示任何内容到文本框中。我试过让一个线程监听管道,另一个线程创建GUI,但在这两种情况下,一个线程似乎总是挂起或GUI永远不会被创建。

有什么建议吗?

3 个答案:

答案 0 :(得分:0)

当我做这样的事情时,我使用了一个单独的线程来监听管道。该线程有一个指针/句柄返回GUI,因此它可以发送要显示的数据。

我想你可以在GUI的更新/事件循环中完成它,但是你必须确保它在管道上进行非阻塞读取。我是在一个单独的线程中完成的,因为我必须对通过的数据进行大量处理。

哦,当你正在进行显示时,请确保一次以非平凡的“块”进行。最大化消息队列(至少在Windows上)将更新命令发送到文本框非常容易。

答案 1 :(得分:0)

过去当我从外部事物(例如:以太网套接字)中读取GUI时,我有一个单独的线程来处理外部事物的服务,以及一个定时回调(通常设置为一半)第二步)更新显示外部数据的GUI小部件。

答案 2 :(得分: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)

(在这种情况下你也会收到回应)