2017-03-09 39 views
3

當試圖弄清楚如何在按下按鈕(利用GPIO管腳)後如何讓python腳本發送左或右擊鍵時,我偶然發現了this question用python模擬Raspbian中的擊鍵

似乎所選的答案是我需要讓我去,但安裝xautomation後,試圖調整代碼到我的腳本和閱讀Popen的文檔(我甚至嘗試運行一個新的與逐字的代碼)我不斷收到以下錯誤文件:

Traceback (most recent call last): 
    File "/home/zdistaging/Documents/xte test.py", line 17, in <module> 
    keypress(shift_a_sequence) 
    File "/home/zdistaging/Documents/xte test.py", line 15, in keypress 
    p.communicate(input=sequence) 
    File "/usr/lib/python3.4/subprocess.py", line 941, in communicate 
    self.stdin.write(input) 
TypeError: 'str' does not support the buffer interface 

我在皮3 B型運行Python3,在Raspbian傑西使用Pixel(從raspberrypi.org下載)

任何想法爲什麼它出錯了?

如果它有幫助,我所要做的就是允許用戶在FEH幻燈片中向左和向右滾動......我可能完全脫離這個方法,給出了這個任務看似簡單的任務是。我不是在尋找某個人爲我徹底解決這個問題 - 我喜歡與編碼相關的挑戰 - 我只是超新的python;將我推向正確的方向將會非常有幫助。

任何幫助非常感謝!

編輯:對不起,不包括代碼!

from subprocess import Popen, PIPE 

control_f4_sequence = '''keydown Control_L 
key F4 
keyup Control_L 
''' 

shift_a_sequence = '''keydown Shift_L 
key A 
keyup Shift_L 
''' 

def keypress(sequence): 
    p = Popen(['xte'], stdin=PIPE) 
    p.communicate(input=sequence) 

keypress(shift_a_sequence) 
keypress(control_f4_sequence) 

編輯編輯:

這裏是我更新的代碼...它實際打印的左,右按鍵操作空間。

import time 
import RPi.GPIO as GPIO 
from subprocess import Popen, PIPE 
GPIO.setmode(GPIO.BCM) 
GPIO.setwarnings(False) 

leftArrow = '''key \x1B[D''' # I've tried '''key Left''' 
rightArrow = '''key \x1B[C''' # and '''key Right''' with the same results 

offButton = 26  # Black wire 
onButton = 19  # White wire 
leftButton = 13  # Red wire 
rightButton = 6  # Green wire 


def keypress(sequence): 
    if isinstance(sequence, str): 
     sequence = sequence.encode('ascii') 
    p = Popen(['xte'], stdin=PIPE) 
    p.communicate(input=sequence) 


GPIO.setup(offButton, GPIO.IN, GPIO.PUD_UP) 
GPIO.setup(onButton, GPIO.IN, GPIO.PUD_UP) 
GPIO.setup(leftButton, GPIO.IN, GPIO.PUD_UP) 
GPIO.setup(rightButton, GPIO.IN, GPIO.PUD_UP) 


while True: 
    offButton_state = GPIO.input(offButton) 
    onButton_state = GPIO.input(onButton) 
    leftButton_state = GPIO.input(leftButton) 
    rightButton_state = GPIO.input(rightButton) 

    if offButton_state == GPIO.LOW: 
     print("Off button pressed") 

    if onButton_state == GPIO.LOW: 
     print("On button pressed") 

    if leftButton_state == GPIO.LOW: 
     keypress(leftArrow) 
     print("Left button pressed") 

    if rightButton_state == GPIO.LOW: 
     keypress(rightArrow) 
     print("Right button pressed") 

    time.sleep(1) 

我已經閱讀了關於subprocess and Popen.communicate(),但無法真正判斷問題是否有事可做與或有什麼xte is expecting as an argument。思考?

+1

請將相關的代碼添加到您的問題! –

回答

1

該錯誤表明您的控制序列是字符串(即unicode),但Subprocess似乎期望字節。

在功能keypress,轉換序列爲字節就像這樣:

if isinstance(sequence, str): 
    sequence = sequence.encode('ascii') 

關於字節串很好的書面記錄,和Unicode可以在這裏找到:https://nedbatchelder.com/text/unipain.html

+0

聖牛!這就像一個魅力,非常感謝!儘管我爲左右箭頭定義了不同的序列,但它們正在做一些奇怪的事情,但都給了我空間。 –

+0

另外,這是一個很棒的寫作,感謝分享! –

0

我一直在尋找同樣的例子,下面是6個按鈕我的工作例如:(它有點亂,但我調試行可能會幫助別人太)

import time 
import RPi.GPIO as GPIO 
GPIO.setmode(GPIO.BCM) 
GPIO.setwarnings(False) 
from Xlib import X 
from subprocess import Popen, PIPE 

buttons = [18,   23,   24,   25,  8,  7 ] 
opcodes = ['next', 'enter', 'alt tab', 'previous', 'spacebar', 'shift' ] 
opcodes2 = ['key Left ', 'key Up ', 'key Down ', 'key Right ', 'key Enter ', 'key Shift_L '] 

# set the gpio pins 
for button in buttons: 
    GPIO.setup(button, GPIO.IN, GPIO.PUD_UP) 

def keypress(sequence): 
    #if isinstance(sequence, str): 
    #sequence = sequence.encode('ascii') 
    p = Popen(['xte', '-x:0'], stdin=PIPE) 
    p.communicate(input=sequence) 

def main(): 
    while True: 
     button_state = [] 
     for button in buttons: 
      button_state.append(GPIO.input(button)) 

     for item in range(len(button_state)): 
      if button_state[item] == 0: 
       print (opcodes2[item]) #debugging 
      # send X key for keystroke in (for the given iteration of the loop) opcodes[button.output(index)] 
       #print (repr(str(opcodes2[item]).encode('ascii'))) 
       keypress(str(opcodes2[item]).encode('ascii')) 
     print (repr(button_state)) #for debugging 
     time.sleep(0.3) 
     del button_state 

if __name__ == '__main__': 
    main() 

注意每個命令的opcodes2內的尾隨空格(可以是任何字符)。 ascii編碼丟棄了我的最後一個字符,所以這是我有點醜陋的解決方法。