RPi - программа Python Curses, запущенная при загрузке, не имеет фокуса клавиатуры - PullRequest
0 голосов
/ 06 января 2019

Я пытаюсь написать программу, которая будет запускаться при запуске моего raspberry pi и позволит мне сразу же начать набирать текст с помощью клавиатуры, и она будет подхвачена программой. Я не хочу вручную запускать программу при запуске пи. Мне нужно использовать curses (или подобную небуферизованную библиотеку ввода с клавиатуры), потому что я отображаю то, что я печатаю, на ЖК-дисплее 2x16 I2C, но мне также нужно, чтобы все, что я печатаю, записывалось в текстовый файл.

Прямо сейчас я автоматически запускаю программу при загрузке, помещая строку в rc.local. Это работает, и дисплей I2C правильно отображает вывод программы, но он не реагирует на ввод с клавиатуры, а вместо этого отображается ввод с клавиатуры (когда я подключаю круговую диаграмму к экрану, цель состоит в том, чтобы запустить безголовый) на странной консоли раскладка, которая выходит, когда я нажимаю клавишу ввода, и говорит -bash: команда «что бы я только что набрал» не найдена.

Я уже пробовал:

  1. Установка таймера в начале программы для ожидания полной загрузки pi перед инициализацией окна curses и захвата клавиатуры

  2. Создание отдельной программы на Python для ожидания полной загрузки pi и последующего запуска основного сценария путем его импорта

Хотя ни один из этих методов не работает, я получаю ту же проблему с небольшими отличиями.

Чтобы было понятно, программа работает без нареканий, если я запускаю ее вручную из командной строки. Но в программе нет ввода с клавиатуры (или, по крайней мере, не там, где он должен быть введен), когда я автоматически запускаю скрипт с помощью rc.local.

Мой код:

 #!/usr/bin/python
import I2C_LCD_driver, datetime, sys
from time import *
from subprocess import call

mylcd = I2C_LCD_driver.lcd()

for x in range(30): #waits for raspberry pi to boot up
    mylcd.lcd_display_string("Booting Up: "+str(x), 1)
    sleep(1)

import curses
key = curses.initscr()
curses.cbreak()
curses.noecho()
key.keypad(1)
key.nodelay(1)

escape=0
while escape==0:
    #variable initialization

    while 1:
        k=key.getch()
        if k>-1: #runs when you hit any key. getch() returns -1 until a key is pressed
            if k==27: #exits the program when you hit Esc
                break
            elif k==269:
                # a couple other special Function key cases are here
            else:
                inpt=chr(k)
                mylcd.lcd_display_string(inpt,2,step) #writes the last character to the display
                #some more code that handles writing the text to the LCD, which works flawlessly when run manually.

    file.write("%s\r\n" % entry)
    file.close()
    mylcd.lcd_display_string("Saved           ",2)
    mylcd.lcd_display_string("F1 New F2 PwrOff",1)
    while 1:
        k=key.getch()
        if k>-1:
            if k==265: #do it again! with F1
                mylcd.lcd_clear()
                break
            elif k==266: #shut down with F2
                escape=1
                break
curses.nocbreak()
key.keypad(0)
curses.echo()
curses.endwin()
call("sudo shutdown -h now", shell=True)

Строка, которую я имею в /etc/rc.local, выглядит следующим образом, если это важно:

sudo python3 journal.py &

и за ним следует строка «exit 0». Спасибо за любую помощь, которую вы можете предоставить. Я знаю, что это очень специфическая проблема, и воспроизвести ее будет утомительно, но если кто-нибудь знает что-либо об функциях автозапуска, я был бы очень признателен за любые советы.

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Хорошо, буквально все, что мне нужно было сделать (что я нашел после более подробного исследования stackexchange, this - это поток, содержащий ответ, который я искал), - запустить мою программу из ~ /. bashrc вместо /etc/rc.local. Этот метод работает отлично, именно то, что я хотел.

0 голосов
/ 07 января 2019

Это должно быть из-за того, как вы вызвали программу:

python3 journal.py &

Вы можете проверить РУКОВОДСТВО ПО РАБОТЕ страницы руководства по bash (или вашей оболочке):

Только передний план процессы могут читать из ... терминала. Фоновые процессы, которые попытка чтения из ... терминал посылает сигнал SIGTTIN ... терминалом ядра драйвер, который, если не пойман, приостанавливает процесс.

Короче говоря, как только проклятия (или что-то в этом роде) пытаются прочитать из stdin ваш процесс, вероятно, остановлен (после того, как он, возможно, уже записан на ваш дисплей). Держите его на переднем плане, чтобы иметь возможность использовать stdin (и с помощью дополнительной клавиатуры).

Примечание: Не уверен насчет дистрибутива и деталей реализации rc.local в вашем случае, но разве скрипты init обычно не запускаются с uid / gid 0 (без переноса отдельных вызовов через sudo?)

...