So implementieren Sie die Time-Wait-Verarbeitung mit wxpython

Einführung

Das erste Mal habe ich versucht, mit wxpython einen Time-Wait-Prozess zu schreiben

  1. Warten Sie eine Weile mit time.sleep ()
  2. Der Bildschirm reagiert nicht mehr und die Ursache wird untersucht.
  3. Unterstützung mit wx.Timer und Thread

Ich denke, Sie werden dem Weg folgen. (Ist es nicht?) Ich habe diesen Wartevorgang notiert, weil ich ihn ziemlich oft benutze.

Ehrlich gesagt, dieser Inhalt ist allgegenwärtig, also hoffe ich, dass Sie ihn in einem der Referenzartikel sehen können.

Fehlerursache in time.sleep ()

Grob gesagt ist die Ursache, dass der Mainloop, der hinter der GUI läuft, im Schlaf stoppt.

Umgebung

Mac OS wxpython 4.1.0

importieren

Installieren Sie wxpython

python


pip install wxpython

Das Einfädeln kann ohne Installation verwendet werden. Wird bei Verwendung von wx.Timer nicht verwendet, sondern verwendet Zeit.

python


import wx
import threading
import time

Methode 1 wx.Timer

Dies ist effektiv, wenn die Verarbeitung in regelmäßigen Abständen durchgeführt wird. Ist es am einfachsten, die aktuelle Uhrzeit zu aktualisieren? WxTimer1.gif

python


import wx
import threading  #Diesmal nicht verwendet
import time  #Diesmal nicht verwendet
#Wird zur Zeitanzeige verwendet
import datetime as dt


class MainFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(400, 200))

        #TimerPanel-Instanzerstellung
        self.panel = TimerPanel(self, -1)

        #Anzeige mit zentriertem Bildschirm
        self.Center()
        self.Show()


class TimerPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id)

        #Erstellen einer Zeichenfolge der aktuellen Zeit, self.clock_txt-Erstellung,Anzeigezeit
        now = dt.datetime.now().strftime('%Y/%m/%d %H:%M:%S')
        self.clock_txt = wx.StaticText(self, -1, label=now)

        #Schriftarteinstellungen,Nach dem Ändern der Größe auf 20 selbst.clock_Reflektiert in txt
        font = wx.Font(20, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        self.clock_txt.SetFont(font)

        #Sizer erstellen, self.clock_Fügen Sie txt zu sizer hinzu,Wenden Sie den Sizer auf das Panel an
        sizer = wx.GridSizer(1, 1, gap=(0, 0))
        sizer.Add(self.clock_txt, flag=wx.ALIGN_CENTRE)  # ALIGN_MITTE: Wird in der Mitte des Messgeräts installiert
        self.SetSizer(sizer)

        self.timer = wx.Timer(self)  #Erstellen Sie einen Timer im Bedienfeld
        self.Bind(wx.EVT_TIMER, self.clock)  #Selbst in festgelegten Intervallen.Uhr laufen lassen
        self.timer.Start(1000)  #1000ms Timer(=1s)Zum Starten einstellen
        # self.timer.Stop()  #Wenn Sie den Timer stoppen möchten


    def clock(self, event):
        #Holen Sie sich die aktuelle Zeit und Selbst.clock_In txt setzen
        now = dt.datetime.now().strftime('%Y/%m/%d %H:%M:%S')
        self.clock_txt.SetLabel(now)
        self.Refresh()


if __name__ == '__main__':
    app = wx.App()
    MainFrame(None, -1, 'TimeEvent')
    app.MainLoop()

Erstellen Sie einen Timer mit dem Rahmen oder Bedienfeld als übergeordnetem Element, legen Sie das Intervall fest und beginnen Sie. Es können mehrere Timer gleichzeitig ausgeführt werden.

WxTimer2.gif

Das GIF oben hat zwei Felder, in denen jeweils die Uhrzeit mit einem Timer angezeigt wird.

Das obere Feld ist 1 Sekunde und das untere 2 Sekunden.

Methode 2 Parallelverarbeitung Threading.Thread

wx.Timer verwendet threading.Thread für die Verarbeitung, die schwer zu implementieren ist. Diese Funktion kann einen anderen Thread erstellen und mehrere Prozesse gleichzeitig ausführen. Sie sollten time.sleep () nicht in dem Thread verwenden, in dem die GUI ausgeführt wird, aber in einem anderen Thread gibt es kein Problem.

Das Folgende ist der Prozess, den ich mit wx.Timer schwierig finde

Mit anderen Worten, verwenden Sie threadind.Thred, wenn Sie eine Ampel machen (ist es nicht zu begrenzt?)

WxThread1.gif

Blau, Gelb und Rot werden jeweils 4, 1 und 5 Sekunden lang angezeigt.

python


import wx
import time
import threading


class TrafficLight(threading.Thread):
    def __init__(self, panel):
        super().__init__()
        self.panel = panel
        #Dämonisieren Sie den Subthread. Wenn dieser nicht auf True gesetzt ist, wird der Subthread auch dann weiter ausgeführt, wenn der Bildschirm geschlossen wird.
        self.setDaemon(True)

    def run(self):
        while True:
            #Gelbes Feld->schwarz,Rotes Feld->rot
            self.panel.yellow_panel.SetBackgroundColour('#000000')
            self.panel.red_panel.SetBackgroundColour('#ff0000')
            self.panel.Refresh()
            time.sleep(5)

            #Rotes Feld->schwarz,Blaue Tafel->Blau
            self.panel.red_panel.SetBackgroundColour('#000000')
            self.panel.blue_panel.SetBackgroundColour('#00ff00')
            self.panel.Refresh()
            time.sleep(4)

            #Blaue Tafel->schwarz,Gelbes Feld->Gelb
            self.panel.blue_panel.SetBackgroundColour('#000000')
            self.panel.yellow_panel.SetBackgroundColour('#ffff00')
            self.panel.Refresh()
            time.sleep(1)


class MainFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(600, 200))

        self.main_panel = MainPanel(self, -1)
        
        #Zeigen Sie den Bildschirm in der Mitte an
        self.Center()
        self.Show()


class MainPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id)
        
        #Blaues Feld, Farbe als schwarz angegeben
        self.blue_panel = wx.Panel(self, -1)
        self.blue_panel.SetBackgroundColour('#000000')
        
        #Gelbes Feld, Farbe als schwarz angegeben
        self.yellow_panel = wx.Panel(self, -1)
        self.yellow_panel.SetBackgroundColour('#000000')

        #Rotes Feld, Farbe als schwarz angegeben
        self.red_panel = wx.Panel(self, -1)
        self.red_panel.SetBackgroundColour('#000000')
        
        #Start Knopf
        self.button = wx.Button(self, -1, 'start')
        
        #Layoutbezogen
        sizer1 = wx.FlexGridSizer(2, 1, gap=(0, 0))
        sizer2 = wx.GridSizer(1, 3, gap=(0, 0))

        sizer1.Add(sizer2, flag=wx.EXPAND)
        sizer1.Add(self.button, flag=wx.ALIGN_RIGHT)
        sizer1.AddGrowableCol(0)
        sizer1.AddGrowableRow(0)

        sizer2.Add(self.blue_panel, flag=wx.EXPAND)
        sizer2.Add(self.yellow_panel, flag=wx.EXPAND)
        sizer2.Add(self.red_panel, flag=wx.EXPAND)
        self.SetSizer(sizer1)
        
        #Erstellung von Subthread-Instanzen, selbst zum Argument
        self.traffic_light = TrafficLight(self)
        
        #Tastenereignis
        self.button.Bind(wx.EVT_BUTTON, self.start)

    def start(self, event):
        #Erstellung von Subthread-Instanzen, selbst zum Argument
        traffic_light = TrafficLight(self)
        #Subthread-Vorgang gestartet
        traffic_light.start()
        self.start_button.Disable()  #Schaltfläche deaktivieren,Verhindern Sie, dass mehrere Threads erstellt werden

if __name__ == "__main__":
    app = wx.App()
    MainFrame(None, -1, "Ampel")
    app.MainLoop()

Überschreiben der Ausführungsmethode für Threading.Thread. Nur self kann an die run-Methode übergeben werden. Die erforderlichen Attribute werden beim Erstellen der Instanz übergeben. Da es nur einmal pro Thread ausgeführt werden kann, wird es beim Drücken der Taste instanziiert.

Thread jederzeit beenden

Die obige Ampel kann nicht angehalten werden, da sie sich bewegt, während True. Aber ich möchte es aufhalten können. Schreiben Sie daher die TrafficLight-Klasse neu und fügen Sie globale Variablen und Funktionen hinzu.

Die GUI hat eine Stoppschaltfläche hinzugefügt. Wenn die Stopp-Taste gedrückt wird, wird thread_stop_flag zu True und der Thread-Vorgang endet.

WxThread

python


import wx
import time
import threading

thread_stop_flag = False


def wait_time(seconds):
    """
Halten Sie während der verstrichenen Wartezeit an_Warten Sie, während Sie auf die Flagge schauen
    stop_Beenden Sie die while-Anweisung, wenn das Flag True ist
    :param seconds: int
Wartezeit
    :return: None
    """
    wait_start = time.time()
    while time.time() - wait_start <= seconds:
        if not thread_stop_flag:
            time.sleep(1)
        else:
            break


class TrafficLight(threading.Thread):
    def __init__(self, panel):
        super().__init__()
        self.panel = panel
        #Dämonisieren Sie den Subthread. Wenn dieser nicht auf True gesetzt ist, wird der Subthread auch dann weiter ausgeführt, wenn der Bildschirm geschlossen wird.
        self.setDaemon(True)

    def run(self):
        while not thread_stop_flag:  #Änderung 2
            #Gelbes Feld->schwarz,Rotes Feld->rot
            self.panel.yellow_panel.SetBackgroundColour('#000000')
            self.panel.red_panel.SetBackgroundColour('#ff0000')
            self.panel.Refresh()
            wait_time(5)

            #Rotes Feld->schwarz,Blaue Tafel->Blau
            self.panel.red_panel.SetBackgroundColour('#000000')
            self.panel.blue_panel.SetBackgroundColour('#00ff00')
            self.panel.Refresh()
            wait_time(4)

            #Blaue Tafel->schwarz,Gelbes Feld->Gelb
            self.panel.blue_panel.SetBackgroundColour('#000000')
            self.panel.yellow_panel.SetBackgroundColour('#ffff00')
            self.panel.Refresh()
            wait_time(1)

        #Änderung 3,Kehre zu Schwarz zurück
        self.panel.blue_panel.SetBackgroundColour('#000000')
        self.panel.yellow_panel.SetBackgroundColour('#000000')
        self.panel.red_panel.SetBackgroundColour('#000000')
        self.panel.Refresh()


class MainFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(600, 200))

        self.main_panel = MainPanel(self, -1)

        #Zeigen Sie den Bildschirm in der Mitte an
        self.Center()
        self.Show()


class MainPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id)

        #Blaues Feld, Farbe als schwarz angegeben
        self.blue_panel = wx.Panel(self, -1)
        self.blue_panel.SetBackgroundColour('#000000')

        #Gelbes Feld, Farbe als schwarz angegeben
        self.yellow_panel = wx.Panel(self, -1)
        self.yellow_panel.SetBackgroundColour('#000000')

        #Rotes Feld, Farbe als schwarz angegeben
        self.red_panel = wx.Panel(self, -1)
        self.red_panel.SetBackgroundColour('#000000')

        #Start,Taste zum Stoppen
        self.start_button = wx.Button(self, -1, 'start')
        self.stop_button = wx.Button(self, -1, 'stop')

        #Layoutbezogen
        sizer1 = wx.FlexGridSizer(2, 1, gap=(0, 0))
        sizer2 = wx.GridSizer(1, 3, gap=(0, 0))
        sizer3 = wx.GridSizer(1, 2, gap=(0, 0))

        sizer1.Add(sizer2, flag=wx.EXPAND)
        sizer1.Add(sizer3, flag=wx.ALIGN_RIGHT)
        sizer1.AddGrowableCol(0)
        sizer1.AddGrowableRow(0)

        sizer2.Add(self.blue_panel, flag=wx.EXPAND)
        sizer2.Add(self.yellow_panel, flag=wx.EXPAND)
        sizer2.Add(self.red_panel, flag=wx.EXPAND)

        sizer3.Add(self.start_button)
        sizer3.Add(self.stop_button)
        self.SetSizer(sizer1)

        #Tastenereignis
        self.start_button.Bind(wx.EVT_BUTTON, self.start)
        self.stop_button.Bind(wx.EVT_BUTTON, self.stop)

    def start(self, event):
        global thread_stop_flag
        thread_stop_flag = False
        #Erstellung von Subthread-Instanzen, selbst zum Argument
        traffic_light = TrafficLight(self)
        #Subthread-Vorgang gestartet
        traffic_light.start()
        self.start_button.Disable()  #Verhindert die Erstellung von Threads zur Ungültigmachung mehrerer Schaltflächen

    def stop(self, event):
        #Globaler variabler Thread_stop_Flag auf True=Setzen Sie die while-Anweisungsbedingung des Threads auf False
        global thread_stop_flag
        thread_stop_flag = True
        self.start_button.Enable()


if __name__ == "__main__":
    app = wx.App()
    MainFrame(None, -1, "Ampel")
    app.MainLoop()

Es ist keine große Sache, aber es fühlt sich nach einer langen Zeit an. Bitte lassen Sie mich wissen, ob es einen anderen guten Weg gibt, um zu schreiben ...

Am Ende

Danke fürs Lesen. Natürlich hat das Verfahren mit Threading neben Ampeln noch andere Verwendungszwecke. Zum Beispiel, wenn Sie eine Reihe von Vorgängen nur einmal anstatt in regelmäßigen Abständen ausführen möchten. Ich benutze es für Geräte-Grundeinstellungen.

Referenzartikel

Ich verweise auf die folgenden Artikel.

Fehlerursache Python - ich bin ein Anfänger. Nach dem Einfügen der Sleep-Anweisung funktionierte die App nicht mehr ordnungsgemäß. | teratail

Fadenbruch Ihr threading.Event wird falsch verwendet - Qiita

Recommended Posts

So implementieren Sie die Time-Wait-Verarbeitung mit wxpython
So führen Sie eine Mehrkern-Parallelverarbeitung mit Python durch
So messen Sie die Ausführungszeit mit Python Teil 1
[wxpython] Verwendung der Basis- und Zeitachse von wx.lib.plot
So messen Sie die Ausführungszeit mit Python Part 2
So messen Sie die Verarbeitungszeit mit Python oder Java
So messen Sie die Wiedergabezeit von MP3-Dateien mit Python
Wie aktualisiere ich mit SQLAlchemy?
Wie man mit Theano besetzt
Wie mit SQLAlchemy ändern?
So trennen Sie Zeichenfolgen mit ','
Wie man RDP auf Fedora31 macht
Wie lösche ich mit SQLAlchemy?
So brechen Sie RT mit tweepy ab
Python: So verwenden Sie Async mit
So verwenden Sie virtualenv mit PowerShell
So installieren Sie Python-Pip mit Ubuntu20.04LTS
Umgang mit unausgeglichenen Daten
Wie fange ich mit Scrapy an?
Erste Schritte mit Python
Umgang mit dem DistributionNotFound-Fehler
Wie fange ich mit Django an?
Aufblasen von Daten (Datenerweiterung) mit PyTorch
So berechnen Sie das Datum mit Python
So installieren Sie den MySQL-Connector mit pip3
So verbinden Sie INNER mit SQL Alchemy
So installieren Sie Anaconda mit pyenv
So extrahieren Sie Funktionen von Zeitreihendaten mit PySpark Basics
Fassen Sie mit tf.data.Dataset api zusammen, wie Text (Verarbeitung natürlicher Sprache) vorverarbeitet wird
So schreiben Sie offline in Echtzeit Lösen von F01-Problemen mit Python
So berechnen Sie "xx time" in einem Schuss mit Python timedelta
So führen Sie eine arithmetische Verarbeitung mit der Django-Vorlage durch
[Blender] So legen Sie shape_key mit dem Skript fest
Wie man mit matplotlib mehrere Figuren betitelt
So erhalten Sie die Eltern-ID mit sqlalchemy
So vergleichen Sie Zeitreihendaten-Derivative DTW, DTW-
So fügen Sie ein Paket mit PyCharm hinzu
So stellen Sie die Serverzeit auf japanische Zeit ein
So installieren Sie DLIB mit aktiviertem 2020 / CUDA
Wie man offline in Echtzeit schreibt Ich habe versucht, E11 mit Python zu lösen
Verwendung von ManyToManyField mit Djangos Admin
Verwendung von OpenVPN mit Ubuntu 18.04.3 LTS
Verwendung von Cmder mit PyCharm (Windows)
So ermitteln Sie mit Python den Unterschied zwischen Datum und Uhrzeit in Sekunden
So verhindern Sie Paketaktualisierungen mit apt
So arbeiten Sie mit BigQuery in Python
Wie man Ass / Alembic mit HtoA benutzt
Umgang mit Enum-Kompatibilitätsfehlern
Verwendung von Japanisch mit NLTK-Plot
Wie man einen Taschentest mit Python macht
So suchen Sie in Google Colaboratory nach Google Drive
So zeigen Sie Python-Japanisch mit Lolipop an
So laden Sie YouTube-Videos mit youtube-dl herunter
Verwendung des Jupyter-Notebooks mit ABCI
So schalten Sie Linux unter Ultra96-V2 aus