Hallo
und vielen Dank für die schnellen und ausführlichen Antworten.
Ich hielt es für sinnvoll, nur den meiner Meinung nach wesentlichen Code zu posten, sehe jetzt aber ein, dass es so nicht möglich ist, eine vollständig geeignete Antwort zu erstellen.
Daher einige zusätzliche Informationen:
Für das oben angesprochene Radioprojekt soll auf dem Display einerseits das Logo des aktuellen Senders dargestellt werden und darunter in einem Laufband Infos zum aktuellen Titel.
Das Display spreche ich über einen Treiber direkt im Programm an. So erspare ich mir X11 und kann das Script direkt über die SSH-Kommandozeile starten. Für das GUI benutze ich wie oben angegeben das Modul PIL. Da ich aufgrund der Einbaus in ein Gehäuse den Inhalt des Displays drehen muss, werden die beiden o.a. Fenster in ein Backgroundimage kopiert - anderenfalls erfolgt eine fehlerhafte Darstellung.
Meine RF-Fernbedienung sendet ihre Inhalte nicht nur über /dev/input/event0, sondern auch über .../event1 bis .../event 3. Dies kann ich mit der Library "evdev" gut behandeln.
Zu meinen - beschränkten - Fähigkeiten:
Ich bin relativ neu in Python und habe nicht den Anspruch alles umfänglich zu beherrschen. Jedoch erwarte ich keine fertigen Lösungen und bin bereit mich in das Thema zu vertiefen, soweit es das Projekt erfordert. So habe ich mich durchaus mit dem Thema Threads und Asyncio beschäftigt, jedoch gelingt mir hier ein übergreifendes Verständnis nur schwer. Aber bisher ist es mir immer ganz gut gelungen, im Netz gefundene Teile zu einem gewünschten Ganzen zusammenzufügen.
@Sirius3:
So habe ich mir eine Lösung im Prinzip gewünscht, vielen Dank dafür. Leider ist es so, dass die Laufschrift jetzt nicht mehr ruckelfrei läuft, so wie in meiner angegebenen reinen Schleife. Die Ursache vermute ich in der Zeile
Vielleicht ist Python dafür doch nicht die geeignete Wahl. Weiterhin verhält sich die - von mir in deinem Code angepasste - Funktion getkey() nicht mehr wie erwartet. In meinem oben geposteten Code wird nur auf KeyUp reagiert
um die von der FB gesendeten Mehrfach-Events zu unterdrücken.
Wenn ich diesen Code in deinen einbringe, wird ein Code für einen Key erst bei mehrfacher Betätigung erzeugt, ansonsten erscheint immer nur der Wert 4. Hier mögliche Interferenzen verschiedener Eventbehandlungen überschaue ich leider nicht.
Hier nun mein gesamter Code, mit deinem integriert und an manchen Stellen anpasst.
Code: Alles auswählen
#!/usr/bin/env python3
import time
import os
import ST7789
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from evdev import InputDevice
from selectors import DefaultSelector, EVENT_READ
message = "Hello World! How are you today?"
RF_KEY_RIGHT = 106
selector = DefaultSelector()
keybd0 = InputDevice('/dev/input/event0')
keybd1 = InputDevice('/dev/input/event1')
keybd2 = InputDevice('/dev/input/event2')
keybd3 = InputDevice('/dev/input/event3')
# This works because InputDevice has a `fileno()` method.
selector.register(keybd0, EVENT_READ)
selector.register(keybd1, EVENT_READ)
selector.register(keybd2, EVENT_READ)
selector.register(keybd3, EVENT_READ)
# Create ST7789 LCD display class.
disp = ST7789.ST7789(
height=240,
width=240,
rotation=270,
port=0,
cs=ST7789.BG_SPI_CS_FRONT, # BG_SPI_CS_BACK or BG_SPI_CS_FRONT
dc=9,
backlight=19, # 18 for back BG slot, 19 for front BG slot.
spi_speed_hz=80 * 1000 * 1000,
offset_left=0,
offset_top=0
)
# Initialize display.
disp.begin()
img_bg = Image.new('RGB', (240,240), color=(180, 180, 180))
img_scroll = Image.new('RGB', (240,60))
img_draw = ImageDraw.Draw(img_scroll)
img_station = Image.open("e_ndr2.png")
img_bg.paste(img_station,(0,0))
sfont = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 40)
class Ticker:
def __init__(self, message, font, text_x, text_y, draw, img_bg, img_scroll):
self.message = message
self.font = font
self.img_draw = img_draw
self.img_bg = img_bg
self.img_scroll = img_scroll
self.size_x = img_draw.textlength(message, font)
self.size_y = 30
self.text_x = text_x
self.text_y = text_y
self.start = time.time()
self.last_x = None
def update(self, disp):
new_x = int((time.time() - self.start) * 25)
new_x = self.text_x - new_x % (self.size_x + disp.width)
if new_x != self.last_x:
self.img_draw.rectangle((0, self.text_y - 15, disp.width, self.text_y + 45), (226, 226, 226))
self.img_draw.text((new_x, self.text_y), self.message, font=self.font, fill=(0, 0, 0))
self.img_bg.paste(self.img_scroll, (0, 179))
disp.display(self.img_bg)
self.last_x = new_x
def get_key():
for key, mask in selector.select():
device = key.fileobj
for event in device.read():
print(event) #Test
if event.code != 4:
if event.type == 1: # Keypress
if event.value == 0: # reagiert auf Up-Key um Mutlikey zu vermeiden
return event.code
return None #bzw. return event.code zur Testausgabe
def main():
ticker = Ticker(message, sfont, 240, 15, img_draw, img_bg, img_scroll)
while True:
ticker.update(disp)
if selector.select(timeout=0.1):
key = get_key()
if key == RF_KEY_RIGHT:
print(key) #Test
if __name__ == "__main__":
main()