События касания Pygame PiTFT - основной l oop сидит в ожидании обнаружения касаний - PullRequest
2 голосов
/ 18 февраля 2020

Я использую Raspberry Pi и PiTFT для измерения датчиков и отображения результатов. Используя подсказки из { ссылка } все работает нормально, но есть одна проблема: основной l oop ждет, пока не дотронется до lcd. Я удалил все нетривиальные части из программы только для проверки основного l oop. Этот фрагмент кода печатает состояние после касания и отпускания. Пока сенсорный ЖК-дисплей касается основного, l oop продолжает печатать, отпускание ЖК-дисплея останавливает l oop. Как мне переписать l oop, чтобы он продолжал работать, даже когда нет нажатия клавиш?

#!/usr/bin/python3
import subprocess, pygame, evdev, select
pygame.init()
surfaceSize = (320, 240)
##
# Everything that follows is for handling the touchscreen touch events via evdev
##

# Used to map touch event from the screen hardware to the pygame surface pixels.
# (Those values have been found empirically, but I'm working on a simple interactive calibration tool
tftOrig = (3750, 180)
tftEnd = (150, 3750)
tftDelta = (tftEnd [0] - tftOrig [0], tftEnd [1] - tftOrig [1])
tftAbsDelta = (abs(tftEnd [0] - tftOrig [0]), abs(tftEnd [1] - tftOrig [1]))

# We use evdev to read events from our touchscreen
# (The device must exist and be properly installed for this to work)
touch = evdev.InputDevice('/dev/input/touchscreen')

# We make sure the events from the touchscreen will be handled only by this program
# (so the mouse pointer won't move on X when we touch the TFT screen)
touch.grab()
# Prints some info on how evdev sees our input device
print(touch)
# Even more info for curious people
#print(touch.capabilities())

# Here we convert the evdev "hardware" touch coordinates into pygame surface pixel coordinates
def getPixelsFromCoordinates(coords):
    # TODO check divide by 0!
    if tftDelta [0] < 0:
        x = float(tftAbsDelta [0] - coords [0] + tftEnd [0]) / float(tftAbsDelta [0]) * float(surfaceSize [0])
    else:
        x = float(coords [0] - tftOrig [0]) / float(tftAbsDelta [0]) * float(surfaceSize [0])
    if tftDelta [1] < 0:
        y = float(tftAbsDelta [1] - coords [1] + tftEnd [1]) / float(tftAbsDelta [1]) * float(surfaceSize [1])
    else:
        y = float(coords [1] - tftOrig [1]) / float(tftAbsDelta [1]) * float(surfaceSize [1])
    return (int(x), int(y))


# Was useful to see what pieces I would need from the evdev events
def printEvent(event):
    print(evdev.categorize(event))
    print("Value: {0}".format(event.value))
    print("Type: {0}".format(event.type))
    print("Code: {0}".format(event.code))

while True:

    r,w,x = select.select([touch], [], [])
    for event in touch.read():
        if event.type == evdev.ecodes.EV_ABS:
            if event.code == 1:
                X = event.value
            elif event.code == 0:
                Y = event.value
        elif event.type == evdev.ecodes.EV_KEY:
            if event.code == 330 and event.value == 1:
                printEvent(event)
                p = getPixelsFromCoordinates((X, Y))
                if 12 <= p[0] <= 72 and 210 <= p[1] <= 230:
                    num = 0
                if 92 <= p[0] <= 154 and 210 <= p[1] <= 230:
                    num = 1
                if 173 <= p[0] <= 234 and 210 <= p[1] <= 230:
                    num = 2
                if 255 <= p[0] <= 317 and 210 <= p[1] <= 230:
                    num = 3
                if 290 <= p[0] <= 320 and 0 <= p[1] <= 30:
                    pygame.quit()
                    quit()

    print(num)


pygame.quit()
quit()

1 Ответ

1 голос
/ 19 февраля 2020

Решено! С комментариями @sloth и @Kingsley я переписал код так:

    r,w,x = select.select([touch], [], [], 0)
    if ( touch in r ):
        for event in touch.read():
            if event.type == evdev.ecodes.EV_ABS:
                if event.code == 1:
                    X = event.value
                elif event.code == 0:
                    Y = event.value
            elif event.type == evdev.ecodes.EV_KEY:
                if event.code == 330 and event.value == 1:
                    printEvent(event)

Теперь l oop работает, даже если нет ввода, и ввод работает нормально.

...