WebHU - Programozási kérdések és válaszok

Szálnaplózás a TextCtrl-ba

Megpróbálok értékeket nyomtatni egy szálból egy másik osztályban meghatározott TextCtrl ablakba. A közzétett kód egy lecsupaszított verzió, növeli a háttérszálban lévő értéket, majd nem próbálja kinyomtatni a TextCtrl ablakba.

Megpróbáltam a pubsub használatát, de nem találtam olyan példát, amely elég közel lenne a kódomhoz, hogy "integrálhassam".

Frissítés

Hozzáadtam a szálomat a saját osztályához, és most hibaüzenetet kapok.

Hogyan használhatom a post eseményt, hogy adatokat küldjek a másik osztály textCtrl mezőjébe?

import wx 
import time
import threading

GlobalVar = False

#draws the GUI
class Mywin(wx.Frame): 
    def __init__(self, parent, title): 
    #Frame
       super(Mywin, self).__init__(parent, title = title,size = (500,300))  
       panel = wx.Panel(self) 
    #Constant stream toggle Button  
       self.tbtn =wx.ToggleButton(self, label="Constant Stream", pos=(20, 90))
       self.tbtn.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggle)
    #Text window  
       self.logger = wx.TextCtrl(self, pos=(150,0), size=(400,100), style=wx.TE_MULTILINE | wx.TE_READONLY)
    #Draws and laysout the GUI
       panel.Layout()
       self.Centre() 
       self.Show() 
       self.Fit()

#=====================================================================
    def OnToggle(self,event):  #Toggle on, start background stream
        state = event.GetEventObject().GetValue()
        global GlobalVar

        if state == True:
            GlobalVar = True
            Stream.start()
            event.GetEventObject().SetLabel("Streaming")

        else:
            GlobalVar = False
            event.GetEventObject().SetLabel("Constant Stream")

class StreamThread(threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        global GlobalVar
        IncrementMe = 0
        while GlobalVar == True:
            wx.PostEvent(Mywin.logger.AppendText(str(IncrementMe)))
            print(IncrementMe)
            time.sleep(1)
            IncrementMe = IncrementMe + 1

Stream = StreamThread(1, "Stream_Thread")
Stream.daemon = True

app = wx.App() 
Mywin(None,  'Incrementer') 
app.MainLoop()
del app

Válaszok:


1

Csak annak érdekében, hogy ez működjön, és mivel már bevállalt egy globális változót, csak tegye logger globális változót a self.logger helyett.
Megjegyzés: A self.logger.AppendText(IncrementMe) logger.AppendText(str(IncrementMe))-re kell, hogy váljon, mivel egy int hozzáfűzése fájdalmat okoz.
Ideális esetben, ezt újra kell írnia, hogy a thread legyen Class, akkor használhatja a wx.PostEvent jelet a műveletek kiváltására a MyWin-ben az Eseményhez való kötődéssel.
Lásd: https://wxpython.org/Phoenix/docs/html/events_overview.html https://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

Szerkesztés: Itt van egy publikációs szkript, amely remélhetőleg a helyes irányba mutat.

from threading import Thread
import wx
from wx.lib.pubsub import pub
import time
class WorkThread(Thread):

    def __init__(self):
        """Init Worker Thread Class."""
        Thread.__init__(self)
        self.stop_work_thread = 0
        self.start()  # start the thread
        self.val = 0

    def run(self):
        while True:
            if self.stop_work_thread == 1:
                break
            time.sleep(1)
            self.val += 1
            wx.CallAfter(pub.sendMessage, "update", step=self.val)
        wx.CallAfter(pub.sendMessage, "finish")
        return

    def stop(self):
        self.stop_work_thread = 1

class Progress(wx.Frame):
    def __init__(self, parent, title):
        super(Progress, self).__init__(parent, title = title,size = (500,300))
        self.panel = wx.Panel(self)
        self.start_btn = wx.Button(self.panel, label="Start", pos=(20,50))
        self.start_btn.Bind(wx.EVT_BUTTON, self.onStart)
        self.stop_btn =wx.ToggleButton(self.panel, label="Stop", pos=(20, 90))
        self.stop_btn.Bind(wx.EVT_TOGGLEBUTTON, self.onCancel)
        self.logger = wx.TextCtrl(self.panel, pos=(150,0), size=(200,200), style=wx.TE_MULTILINE | wx.TE_READONLY)
        self.stop_btn.Disable()
        self.Bind(wx.EVT_CLOSE, self.onExit)

    def onUpdate(self, step):
        step = str(step)+'\n'
        self.logger.AppendText(step)

    def onStart(self, event):
        self.logger.Clear()
        pub.subscribe(self.onUpdate, "update")
        pub.subscribe(self.onFinish, "finish")
        btn = event.GetEventObject()
        self.start_btn.Disable()
        self.work = WorkThread()
        Progress(self.panel,'Incrementer')
        self.stop_btn.Enable()

    def onCancel(self, event):
        """Cancel thread process"""
        try:
            self.work.stop()
            self.work.join()
        except:
            pass

    def onFinish(self):
        """thread process finished"""
        try:
            pub.unsubscribe(self.onUpdate, "update")
            pub.unsubscribe(self.onFinish, "finish")
        except:
            pass
        self.start_btn.Enable()
        self.stop_btn.Disable()

    def onExit(self, event):
        self.onCancel(None)
        self.onFinish()
        self.Destroy()

app = wx.App()
frame = Progress(None,'Incrementer')
frame.Show(True)
app.MainLoop()

adja meg itt a kép leírását

16.05.2018
  • Köszönöm a tanácsot Rolf. Sajnos nem működött, nem biztos, hogy azért, mert rosszul implementáltam. Próbáltam eseményeket használni, de nem tudtam egyesíteni a szálkezeléssel. Mi történne, ha megpróbáltam közzétenni a TextCtrl-ba, semmi sem történt, amíg le nem állítom a kódot, és az összes üzenet a képernyőre árad. 16.05.2018
  • Írtam egy cikket a naplózó modul szöveges vezérlőre való átirányításáról - blog.pythonlibrary.org/2013/08/09/ 18.05.2018
  • Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..