Domanda

Sono un po 'perso su come affrontare questo problema, mi piacerebbe scrivere una GUI idealmente usando Tkinter con Python, ma inizialmente ho iniziato con Qt e ha scoperto che il problema si estende sia con tutti i framework GUI o il mio limitato comprensione.

I dati di questo caso è venuta da un tubo di nome, e vorrei per visualizzare ciò che viene attraverso il tubo in una casella di testo. Ho provato con un filo ascoltare sul tubo e un altro di creare l'interfaccia grafica, ma in entrambi i casi un thread sembra sempre per appendere o l'interfaccia grafica non viene mai creato.

Qualche suggerimento?

È stato utile?

Soluzione

Ecco il modo in cui lo farei (su 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()

Prova inviando alcuni dati con:

import win32pipe

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

(si ottiene anche una risposta in questo caso)

Altri suggerimenti

Quando ho fatto qualcosa di simile ho usato un thread separato ascolto sul tubo. Il filo ha avuto un puntatore / manico torna alla GUI in modo che possa inviare i dati da visualizzare.

Immagino che si potrebbe fare in loop di aggiornamento / evento della GUI, ma che avrebbe dovuto fare in modo che sta facendo non bloccante si legge sul tubo. L'ho fatto in un thread separato perché ho dovuto fare un sacco di elaborazione sui dati che è venuto attraverso.

Oh, e quando si sta facendo la visualizzazione, assicuratevi di farlo in non banali "pezzi" alla volta. E 'molto facile al massimo fuori la coda di messaggi (su Windows, almeno) che è l'invio di comandi di aggiornamento per la casella di testo.

In passato, quando ho avuto la lettura dei dati di GUI fuori delle cose esterne (es: prese ethernet), ho avuto un thread separato che gestisce la manutenzione della cosa esterna, e di un callback a tempo (in genere impostato su qualcosa come la metà un secondo) per aggiornare il widget GUI che visualizza i dati esterni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top