python - 删除并替换在 Python 中打印到终端的最后一个字符

标签 python python-3.x terminal character raspberry-pi2

我有这段代码可以读取通过多路复用器和 ADC 连接到我的 GPIO 的 16 个模拟模拟传感器,并将所有内容相应地转换为一个字符,然后将每个字符并排写入我的终端,我如何删除和替换最后打印的特点? 现在它只覆盖最后打印的字符并在它旁边打印新的。这个项目的目的是创建一个老派的短信模拟器。

这是我的代码:

#!/usr/bin/python
import time
import RPi.GPIO as GPIO
import spidev # import the SPI driver
from time import sleep
from array import *
DEBUG = False
vref = 3.3 * 1000 # V-Ref in mV (Vref = VDD for the MCP3002)
resolution = 2**10 # for 10 bits of resolution
calibration = 38 # in mV, to make up for the precision of the components
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
start_time=time.time()
elapsed_time=time.time()
keypressed=0
i=0
keyreleased = False
sensor16=['1','-','\\','/','*','!']
sensor15=['4','G','H','I']
sensor14=['7','P','Q','R','S']
sensor13=['*']
sensor12=['2','A','B','C']
sensor11=['5','J','K','L']
sensor10=['8','T','U','V']
sensor09=['0',' ']
sensor08=['3','D','E','F']
sensor07=['6','M','N','O']
sensor06=['9','W','X','Y','Z']
sensor05=['#']
sensor04=['BACKSPACE']
sensor03=['DELETE ALL']
sensor02=['READ']
sensor01=['TRANSMITE']
sensor=[sensor01,sensor02,sensor03,sensor04,sensor05,sensor06,sensor07,sensor08,sensor09,sensor10,sensor11,sensor12,sensor13,sensor14,sensor15,sensor16]
max_press=[1,1,1,1,1,5,4,4,2,4,4,4,1,5,4,6]
num_press=0
steps=0

# MCP3002 Control bits
#
#   7   6   5   4   3   2   1   0
#   X   1   S   O   M   X   X   X
#
# bit 6 = Start Bit
# S = SGL or \DIFF SGL = 1 = Single Channel, 0 = \DIFF is pseudo         differential
# O = ODD or \SIGN
# in Single Ended Mode (SGL = 1)
#   ODD 0 = CH0 = + GND = - (read CH0)
#       1 = CH1 = + GND = - (read CH1)
# in Pseudo Diff Mode (SGL = 0)
#   ODD 0 = CH0 = IN+, CH1 = IN-
#       1 = CH0 = IN-, CH1 = IN+
#
# M = MSBF
# MSBF = 1 = LSB first format
#        0 = MSB first format
# ------------------------------------------------------------------------------
#events = (uinput.KEY_X, uinput.KEY_H, uinput.KEY_E, uinput.KEY_L, uinput.KEY_O)
#device = uinput.Device(events)

# SPI setup
spi_max_speed = 1000000 # 1 MHz (1.2MHz = max for 2V7 ref/supply)
# reason is that the ADC input cap needs time to get charged to the input level.
CE = 0 # CE0 | CE1, selection of the SPI device
spi = spidev.SpiDev()
spi.open(0,CE) # Open up the communication to the device
spi.max_speed_hz = spi_max_speed

#
# create a function that sets the configuration parameters and gets the results
# from the MCP3002
#
#events = (uinput.KEY_X, uinput.KEY_H, uinput.KEY_E, uinput.KEY_L, uinput.KEY_O)
#device = uinput.Device(events)

def read_mcp3002(channel):
    # see datasheet for more information
    # 8 bit control :
    # X, Strt, SGL|!DIFF, ODD|!SIGN, MSBF, X, X, X
    # 0, 1,    1=SGL,     0 = CH0  , 0   , 0, 0, 0 = 96d
    # 0, 1,    1=SGL,     1 = CH1  , 0   , 0, 0, 0 = 112d
    if channel == 0:
        cmd = 0b01100000
    else:
        cmd = 0b01110000

    if DEBUG : print("cmd = ", cmd)

    spi_data = spi.xfer2([cmd,0]) # send hi_byte, low_byte; receive hi_byte, low_byte

    if DEBUG : print("Raw ADC (hi-byte, low_byte) = {}".format(spi_data))

    # receive data range: 000..3FF (10 bits)
    # MSB first: (set control bit in cmd for LSB first)
    # spidata[0] =  X,  X,  X,  X,  X,  0, B9, B8
    # spidata[1] = B7, B6, B5, B4, B3, B2, B1, B0
    # LSB: mask all but B9 & B8, shift to left and add to the MSB
    adc_data = ((spi_data[0] & 3) << 8) + spi_data[1]
    return adc_data


try:
    while True:
        for x in range(0, 16):  # setting the 4 channels of the multiplexer HIGH or LOW accordinlgy
            if x == 0:
                GPIO.output(7, 0)
                GPIO.output(11, 0)
                GPIO.output(13, 0)
                GPIO.output(15, 0)
            elif x == 1:
                GPIO.output(7, 1)
                GPIO.output(11, 0)
                GPIO.output(13, 0)
                GPIO.output(15, 0)
            elif x == 2:
                GPIO.output(7, 0)
                GPIO.output(11, 1)
                GPIO.output(13, 0)
                GPIO.output(15, 0)
            elif x == 3:
                GPIO.output(7, 1)
                GPIO.output(11, 1)
                GPIO.output(13, 0)
                GPIO.output(15, 0)
            elif x == 4:
                GPIO.output(7, 0)
                GPIO.output(11, 0)
                GPIO.output(13, 1)
                GPIO.output(15, 0)
            elif x == 5:
                GPIO.output(7, 1)
                GPIO.output(11, 0)
                GPIO.output(13, 1)
                GPIO.output(15, 0)
            elif x == 6:
                GPIO.output(7, 0)
                GPIO.output(11, 1)
                GPIO.output(13, 1)
                GPIO.output(15, 0)
            elif x == 7:
                GPIO.output(7, 1)
                GPIO.output(11, 1)
                GPIO.output(13, 1)
                GPIO.output(15, 0)
            elif x == 8:
                GPIO.output(7, 0)
                GPIO.output(11, 0)
                GPIO.output(13, 0)
                GPIO.output(15, 1)
            elif x == 9:
                GPIO.output(7, 1)
                GPIO.output(11, 0)
                GPIO.output(13, 0)
                GPIO.output(15, 1)
            elif x == 10:
                GPIO.output(7, 0)
                GPIO.output(11, 1)
                GPIO.output(13, 0)
                GPIO.output(15, 1)
            elif x == 11:
                GPIO.output(7, 1)
                GPIO.output(11, 1)
                GPIO.output(13, 0)
                GPIO.output(15, 1)
            elif x == 12:
                GPIO.output(7, 0)
                GPIO.output(11, 0)
                GPIO.output(13, 1)
                GPIO.output(15, 1)
            elif x == 13:
                GPIO.output(7, 1)
                GPIO.output(11, 0)
                GPIO.output(13, 1)
                GPIO.output(15, 1)
            elif x == 14:
                GPIO.output(7, 0)
                GPIO.output(11, 1)
                GPIO.output(13, 1)
                GPIO.output(15, 1)
            elif x == 15:
                GPIO.output(7, 1)
                GPIO.output(11, 1)
                GPIO.output(13, 1)
                GPIO.output(15, 1)      
            # average three readings to get a more stable one
            channeldata_1 = read_mcp3002(0) # get CH0 input
            sleep(0.001)
            channeldata_2 = read_mcp3002(0) # get CH0 input
            sleep(0.001)
            channeldata_3 = read_mcp3002(0) # get CH0 input
            channeldata = (channeldata_1+channeldata_2+channeldata_3)/3
            #
            # Voltage = (CHX data * (V-ref [= 3300 mV] * 2 [= 1:2 input divider]) / 1024 [= 10bit resolution]
            #
            voltage = int(round(((channeldata * vref * 2) / resolution),0))+ calibration
            if DEBUG : print("Data (bin)    {0:010b}".format(channeldata))
            if x==15 :      # some problem with this sensor so i had to go and twicked the thresshold
                voltage = voltage - 500
            #time.sleep(0.05)
            if ( voltage > 2500) :   #key is released
                keyreleased = True
            if ( voltage < 2500) :   #key is pressed
                keyreleased=False
                keypressed=x         #define which key is pressed
               # print(i)
                if key == keypressed :
                    while keyreleased == False :

                    #for i in range (max_press[keypressed]):
                        # average three readings to get a more stable one
                        channeldata_1 = read_mcp3002(0) # get CH0 input
                        sleep(0.001)
                        channeldata_2 = read_mcp3002(0) # get CH0 input
                        sleep(0.001)
                        channeldata_3 = read_mcp3002(0) # get CH0 input
                        channeldata = (channeldata_1+channeldata_2+channeldata_3)/3
                        #
                        # Voltage = (CHX data * (V-ref [= 3300 mV] * 2 [= 1:2 input divider]) / 1024 [= 10bit resolution]
                        #
                        voltage = int(round(((channeldata * vref * 2) / resolution),0))+ calibration
                        if DEBUG : print("Data (bin)    {0:010b}".format(channeldata))
                        if x==15 :         # some problem with this sensor so i had to go and twicked the thresshold
                            voltage = voltage - 500
                        #time.sleep(0.05)
                        if ( voltage > 2500) :     #key is released
                            keyreleased = True
                            i=0
                        if i < max_press[keypressed] and keyreleased == False :
                        ########################################################
                        #this is where my characters are printed but i need to #
                        #print them side by side and to delete just the last   #
                        #character if i have to !!!!!!!!!!!                    #
                        ########################################################
                            print("\b", sensor[keypressed][i], end="", flush=True)
                            time.sleep(0.5)
                            i=i+1
                        else :
                            i=0
            GPIO.output(7, 0)
            GPIO.output(11, 0)
            GPIO.output(13, 0)
            GPIO.output(15, 0)
            key = keypressed
            start_time=time.time()
        if DEBUG : print("-----------------")


except KeyboardInterrupt: # Ctrl-C
    if DEBUG : print ("Closing SPI channel")
    spi.close()

def main():
    pass

if __name__ == '__main__':
    main()

知道怎么做吗?

最佳答案

大多数终端在打印退格字符 (ASCII 0x08) 时将插入符号向后移动一次:

sys.stdout.write('...');  # print "..."
time.sleep(1);  # wait a second
sys.stdout.write('\010\010\010Done.\n') # replace "..." with "Done."

要删除文本,只需使用退格字符向后移动,然后写入空格即可。

或者,在大多数终端上:

sys.stdout.write('...');  # print "..."
time.sleep(1);  # wait a second
sys.stdout.write('\033[2K\033[1G')  # erase line and go to beginning of line
sys.stdout.write('Done.\n') # print "Done."

您可以在支持它们的终端(大多数现代终端)上使用以下任何 ANSI 转义序列:

  • '\033[#D': 将光标向左移动 # 个字符。
  • '\033[2K':清除当前行(但不要移动光标)。
  • '\033[1K': 当前位置左侧的清除线。
  • '\033[0K': 当前位置右侧的清除线。
  • '\033[1G': 将光标移动到行首。
  • '\033[#;#f': 将光标移动到特定位置。第一个#是行号,第二个#是列号。

维基百科作为 ANSI Escape Codes 的便捷摘要.

关于python - 删除并替换在 Python 中打印到终端的最后一个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35519157/

相关文章:

python - Django 不在 TestCase 上发送电子邮件,但它在 Shell 上发送

python - 在 Mac OS 上设置 tkinter 图标

python - 我如何检查 python 中的 keyhold

terminal - Grunt/Jshint-Task Watcher终端输出颜色

windows - 如何让 win32 控制台识别 ANSI/VT100 转义序列?

ios - 如何从终端更新 Visual Studio for Mac/Xamarin Studio?

python - 如何在 Python 中将数据从不同的本地/远程进程流式传输到程序的 STDIN 中?

python - json 库将空格字符解释为 "\xa0"

Python从xml中提取数据

python-3.x - 更改 tempfile.NamedTemporaryFile 的字符集