0

我对如何解决这个问题有点迷茫,我想用 Tkinter 和 python 编写一个理想的 GUI,但我最初是从 Qt 开始的,发现问题延伸到所有 GUI 框架或我有限的理解。

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

有什么建议么?

4

3 回答 3

0

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

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

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

于 2009-04-08T21:25:20.367 回答
0

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

于 2009-04-08T21:27:51.843 回答
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)

(在这种情况下,您也会收到回复)

于 2009-04-08T22:21:50.543 回答