Das erste Mal habe ich versucht, mit wxpython einen Time-Wait-Prozess zu schreiben
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.
Grob gesagt ist die Ursache, dass der Mainloop, der hinter der GUI läuft, im Schlaf stoppt.
Mac OS wxpython 4.1.0
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
Dies ist effektiv, wenn die Verarbeitung in regelmäßigen Abständen durchgeführt wird. Ist es am einfachsten, die aktuelle Uhrzeit zu aktualisieren?
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.
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.
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?)
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.
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.
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 ...
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.
Ich verweise auf die folgenden Artikel.
Fadenbruch Ihr threading.Event wird falsch verwendet - Qiita
Recommended Posts