问题
I have built a text field module that has one problem: why does Python IDLE not work for while...break statements?
Originally I didn't have a break statement and this didn't work so I added the break statement and the same problems persisted.
This is a long script. You will need everything in it. Do not run in repl.it, as it will not run. However it does run on IDLE.
https://repl.it/@SUPERMECHM500/TextField
As commented in the script, the while statement at line 610 doesn't load on IDLE, and the break
doesn't work as expected: Continue the code if the TextField.FullOutput object has text.
None of my problems relate to repl.it so don't mention it in your answers. Run and debug this script as a Text file from python IDLE.
回答1:
First, a few minor issues:
def listenforkeys(bool):
bool
is a Python keyword, choose a different variable name. (E.g. flag
.) This or
doesn't work the way you think:
if TextField.FullOutput and TextField.inp != "" or []:
Reread about or
. Don't use the same turtle for TextField
implementation that you use for TextField
utilization as this statement:
t.clear()
wipes out all the actions done with t
by user of TextField
. Use a different turtle. Finally, your call to mainloop()
is in the wrong place. Once you invoke it, your code stops and the tkinker event handler takes over. It generally should be the last thing your code des.
Now the main issue, this utilization code:
while TextField.FullOutput == "": #Hope this works with Windows IDLE...
tm.sleep(0.1)
print("Waiting for input...")
if TextField.FullOutput != "":
print('Data sent to RAM.')
break
Don't loop waiting on the buffer to fill. This really should be an event, but at least a callback. I've rewritten your code below to make this a callback, see the Enter()
function and example usage code. It now works for me in IDLE and at the command prompt. I've also made lots of other little changes to try to clean it up a bit -- some of these may need further testing...
# Text field that can be used universally.
# Created by SUPERMECHM500 @ repl.it
# Full functionallity can only be achieved by using IDLE on Windows.
from turtle import Screen, Turtle, mainloop
class TextField:
TextFieldBorderColor = '#0019fc'
TextFieldBGColor = '#000000'
TextFieldTextColor = '#ffffff'
ShiftedDigits = {'1':'!', '2':'@', '3':'#', '4':'$', '5':'%', '6':'^', '7':'&', '8':'*', '9':'(', '0':')'}
def __init__(self, callBack=None):
self.callBack = callBack
self.turtle = Turtle(visible=False)
self.turtle.speed('fastest')
self.inp = []
self.FullOutput = ""
self.TextSeparation = 7
self.s = self.TextSeparation
self.key_shiftL = False
def DrawTextField(self, Title):
t = self.turtle
t.pensize(1)
t.color(TextField.TextFieldBorderColor)
t.pu()
t.goto(-200, -190)
t.write(Title)
t.goto(-200, -200)
t.pd()
t.goto(200, -200)
t.goto(200, -250)
t.goto(-200, -250)
t.goto(-200, -200)
t.pu()
t.goto(-200, -225)
t.color(TextField.TextFieldBGColor)
t.pensize(48)
t.pd()
t.forward(400)
t.pu()
t.goto(-190, -220)
t.color(TextField.TextFieldTextColor)
# Defines the function for each defined key.
def ShiftLON(self):
print("Capslock toggled.")
self.key_shiftL = not self.key_shiftL
def Space(self):
self.turtle.write(' ')
self.inp.append(' ')
self.turtle.forward(self.s)
def Backspace(self):
try:
self.inp.pop(-1)
except IndexError:
print("Cannot backspace!")
else:
t = self.turtle
t.pensize(15)
t.color(TextField.TextFieldBGColor)
t.forward(10)
t.backward(self.TextSeparation)
t.shape('square')
t.pd()
t.turtlesize(1.3) # <<< Doesn't work on repl.it
t.stamp()
t.pu()
t.color(TextField.TextFieldTextColor)
t.shape('classic')
t.backward(10)
def Period(self):
if self.key_shiftL:
self.turtle.write('>')
self.inp.append('>')
self.turtle.forward(self.s)
else:
self.turtle.write('.')
self.inp.append('.')
self.turtle.forward(self.s)
def Comma(self):
if self.key_shiftL:
self.turtle.write('<')
self.inp.append('<')
self.turtle.forward(self.s)
else:
self.turtle.write(',')
self.inp.append(',')
self.turtle.forward(self.s)
def Enter(self):
if self.inp != []:
print("Joining input log...")
self.turtle.pu()
self.FullOutput = ''.join(self.inp)
print('joined.')
print(self.FullOutput)
print("Output printed.")
try:
self.callBack(self.FullOutput)
print("Data sent to callback.")
except NameError:
print("No callback defined.")
self.turtle.clear()
print("Display cleared.")
def digit(self, d):
if self.key_shiftL:
d = TextField.ShiftedDigits[d]
self.turtle.write(d)
self.inp.append(d)
self.turtle.forward(self.s)
def letter(self, abc):
if self.key_shiftL:
abc = abc.upper()
self.turtle.write(abc)
self.inp.append(abc)
self.turtle.forward(self.s)
def listenforkeys(self, flag): # Whether or not keys are being used for text field.
s = Screen()
if not flag:
for character in 'abcdefghijklmnopqrstuvwxyz':
s.onkey(None, character)
for digit in '0123456789':
s.onkey(None, digit)
s.onkey(None, 'period')
s.onkey(None, 'comma')
s.onkey(None, 'Shift_L')
# s.onkeyrelease(None, 'Shift_L')
s.onkey(None, 'space')
s.onkey(None, 'BackSpace')
s.onkey(None, 'Return')
if self.FullOutput or self.inp:
self.FullOutput = "" # Reset the text field content
self.inp = [] # Reset input log
print("Stopped listening.")
if flag:
for character in 'abcdefghijklmnopqrstuvwxyz':
s.onkey(lambda abc=character: self.letter(abc), character)
for character in '1234567890':
s.onkey(lambda d=character: self.digit(d), character)
s.onkey(self.Period, 'period')
s.onkey(self.Comma, 'comma')
s.onkey(self.ShiftLON, 'Shift_L')
# s.onkeyrelease(self.ShiftLON, 'Shift_L')
s.onkey(self.Space, 'space')
s.onkey(self.Backspace, 'BackSpace')
s.onkey(self.Enter, 'Return')
s.listen()
print("Listening.")
if __name__ == "__main__":
def text_callback(text):
print("Data received by callback.")
textField.listenforkeys(False)
turtle.pu()
print("Pen up.")
turtle.write(text, align='center', font=('Arial', 30, 'normal'))
print("Text written.")
screen = Screen()
screen.setup(500, 500)
textField = TextField(text_callback)
textField.DrawTextField("Enter Text. Note: Shift is capslock. Capslock disables your keys.")
print("Text field drawn.")
textField.listenforkeys(True)
print("Can type.")
turtle = Turtle(visible=False)
mainloop()
来源:https://stackoverflow.com/questions/54634919/building-a-built-in-text-field-for-turtle-while-statement-doesnt-work