1

When I press tab it selects all of the text in the input box unless I set the input box multiline to true but it ends up giving the first post a strange format. I would like tab key to act like it normally does in any other program. I am also getting errors when I press Shift or Caps lock in the shell based on whatever the first key input "if" statement is. Both Shift and Caps lock still end up making the text display properly.

I have tried adding an if statement to avoid tab key errors but it doesn't seem to work. I tried using pass and just a normal print statement.

What I'm using.

Error I'm getting

if ord(e.key) == 9: #tab key TypeError: ord() expected a character, but string of length 0 found

from guizero import *

app = App(bg='#121212',title='Virtual assistant',width=500,height=500)
box=Box(app,width='fill',height=420)
box.bg='light gray'
Spacer_box=Box(box,width='fill',height=5,align='top')
userName='Test Username: '

#A is set as the default text value to test if posting into the box works
#Setting multiline to true changes the first post format but allows for the tab key to work properly 
input_box = TextBox(app,text='A',width='fill',multiline=False,align="left")
input_box.text_size=15
input_box.bg='darkgray'
input_box.text_color='black'
input_box.tk.config(highlightthickness=5,highlightcolor="black")


def key_pressed(e):
    
    #stop tab key from highlighting text only when input_box multiline is set to true
    #in the input_box above
    if ord(e.key) == 9: #Tab key
        print('Tab pressed')
        
    elif ord(e.key) == 13:#Enter key
        #Checks if input box is blank or only white space. 
        if input_box.value.isspace() or len(input_box.value)==0:
            print('Empty')
            input_box.clear()
        
        else:#User's output.
            Textbox=Box(box,width='fill', align='top')
            Usernamers=Text(Textbox, text=userName,align='left')
            Usernamers.tk.config(font=("Impact", 14))
            User_Outputted_Text = Text(Textbox, text=input_box.value,size=15,align='left')
            print('Contains text')
            input_box.clear()
            #Test responce to user
            if User_Outputted_Text.value.lower()=='hi':
                Reply_box=Box(box,width='fill',align='top')
                Digital_AssistantName=Text(Reply_box,text='AI\'s name:',align='left')
                Digital_AssistantName.tk.config(font=("Impact", 14))
                Reply_text = Text(Reply_box,text='Hello, whats up?',size=15,align='left')

            

input_box.when_key_pressed = key_pressed        

app.display()
PurpleLlama
  • 168
  • 1
  • 2
  • 14

1 Answers1

1

Adding this at the beginning of key_pressed function will eliminate the error when Caps Lock/Shift or any key that returns an empty string is pressed.

if e.key=='':
    return

The following has worked in preventing the Tab key from selecting the text

if ord(e.key) == 9: #Tab key
    print('Tab pressed')
    input_box.append(' '*4)
    input_box.disable()
    input_box.after(1,input_box.enable)

Basically I have disabled the widget followed by enabling it after 1 millisecond.

UPDATE

Another approach could be to bind the Tab key to the Entry widget used internally (which can be accessed by using the tk property as stated in the docs). I would recommend this approach over the previous, also, because the append method adds the text at the end, there is no built in method to insert the text at the current location, so you would ultimately end up using the insert method of tkinter.Entry with the index as 'insert'.

def select_none(event):
    input_box.tk.insert('insert',' '*4)
    return 'break'

input_box.tk.bind('<Tab>',select_none)

Using return 'break' at the end of the function prevents other event handlers from being executed.

astqx
  • 2,058
  • 1
  • 10
  • 21
  • Does that mean that `guizero.TextBox` is the equivalent to `tkinter.Text`? – TheLizzard Mar 07 '21 at 23:04
  • Also instead of `" "*4` you can use `"\t"`. Sometimes that is better but sometimes it isn't. – TheLizzard Mar 07 '21 at 23:05
  • @TheLizzard `guizero.TextBox.tk` is equivalent to `tkinter.Entry` – astqx Mar 07 '21 at 23:07
  • It uses `Entry` when multiline is false, I don't see why my answer *wouldn't work* it would be great if you could explain and try it yourself first. – astqx Mar 07 '21 at 23:12
  • The first answer for tab does not full work. You can't go back and insert the tab space into text you have already written. Tk approach works perfectly – PurpleLlama Mar 07 '21 at 23:15
  • @PurpleLlama yes I realized that and updated the answer – astqx Mar 07 '21 at 23:15
  • I was wrong saying that the second approach wouldn't work because I thought that `tkinter.Entry` didn't support marks (line `"insert"`) but apparently it does. I usually use `tkinter.Text` as it has more functionality. – TheLizzard Mar 07 '21 at 23:17