如何禁用 PySimpleGui 中的 return_bind_key?
How can I disable the return_bind_key in PySimpleGui?
我需要在问题回答错误后将 bind_return_key 参数禁用为 false。该参数绑定到 'b1' 键下的提交按钮。我使用了 .update() 方法,它在一周前就开始工作了。它不再有效,我收到此错误:“TypeError: update() 有一个意外的关键字参数 'bind_return_key'”
有解决办法吗?
我尝试过的事情:
- 将要更新的内容从键 'b1' 更改为 'Submit'
- 打开了一个新的项目文件来安装我认为是 4.55.1 的最新版本
import PySimpleGUI as sg
import json
data = {
"question": [
"Q1. What is the equation for force",
"Q2. Define isotope",
"Q3. Define wavelength",
"Q4. Define modal dispersion"
],
"answers": [
"f=ma",
"isotopes are atoms of the same element but with a different number of neutrons",
"the least distance between adjacent particles which are in phase",
"causes light travelling at different angles to arrive at different times"
],
"automark": [
["force=massxacceleration"],
["same number of protons", "different number of neutrons", "same element"],
["minimum distance between adjacent particles", "particles which are in phase"],
["different angles", "different times"]
],
"markscheme": [
["force=massxacceleration"],
["same number of protons", "different number of neutrons", "same element"],
["minimum distance between adjacent particles", "particles which are in phase"],
["different angles", "different times"]
],
"mastery": [
0,
0,
0,
0
],
"incorrect": [
0,
0,
0,
0
]
}
def nextset(no, no2, do_not_stop, list1, list2):
endlist = [] # number in the list represent question number
while not do_not_stop:
if no == 3:
do_not_stop = True
if list2[no] == list1[no2]:
position = list1.index(list2[no])
no += 1
no2 = 0
endlist.append(position)
print(endlist)
else:
no2 += 1
savetoexternal(endlist)
def savetoexternal(endlist):
with open("savefile.json", 'w') as f: # creates external json file to be read from later
json.dump(endlist, f, indent=2)
# main program
def listdata(list1):
do_not_stop = False
no = 0
no2 = 0
list2 = list1.copy()
list2.sort(
reverse=True) # ordered question from highest to lowest while keeping original intact to preserve question number
print(list1)
print(list2)
nextset(no, no2, do_not_stop, list1, list2)
def main():
# initialise the question, question number and answer
question = data['question']
answers = data['answers']
automark = data['automark']
markscheme = data['markscheme']
mastery = data['mastery']
incorrect = data['incorrect']
q_no = 0
max_q_no = 4
sg.theme('DarkBlack') # Adding colour
# Stuff in side the window
layout = [[sg.Text(" "), sg.Text(question[0], key='_Q1_', visible=True),
sg.Text(size=(60, 1), key='-OUTPUT-')],
[sg.Text("correct answer:"), sg.Text(size=(60, 1), key='-OUTPUTA-')],
[sg.Text("automark allows:"), sg.Text(size=(60, 1), key='-OUTPUTB-')],
[sg.Text("your answer was:"), sg.Text(size=(60, 1), key='-OUTPUTC-')],
[sg.Text('Answer here: '), sg.InputText(size=(60, 1), key='-INPUT-', do_not_clear=False)],
[sg.Button('Submit', key='b1', bind_return_key=True), sg.Button('Cancel'), sg.Button('Skip')]]
# Create the Window
window = sg.Window('Rerevise', layout, size=(655, 565))
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel
break
window['_Q1_'].Update(visible=False)
window['-OUTPUT-'].update(question[q_no])
select_not_mastered_question = True
already_correct = False
if all(x == 3 for x in mastery):
print("all questions mastered") # add to gui later
list1 = []
q_no = 0
while q_no < max_q_no:
list1.append(incorrect[q_no])
q_no += 1
q_no = 0
listdata(list1)
if values['-INPUT-'].lower() == answers[q_no]: # list index out of range occurs when all questions are complete, need to add completed screen by using else statement
mastery[q_no] += 1 # need to add to gui
print(mastery)
q_no += 1
if q_no == max_q_no:
q_no = 0
while select_not_mastered_question: # make sures the next question has not already been mastered
if mastery[q_no] == 3:
if q_no == max_q_no:
q_no = 0
q_no += 1
else:
select_not_mastered_question = False
window['-OUTPUT-'].update(question[q_no]) # accepts the answer as correct and moves onto the next question
window['-OUTPUTA-'].update('')
window['-OUTPUTB-'].update('')
window['-OUTPUTC-'].update('')
if all(answer in values['-INPUT-'].lower() for answer in automark[q_no]):
print(automark[q_no])
mastery[q_no] += 1 # need to add to gui
print(mastery)
q_no += 1
if q_no == max_q_no:
q_no = 0
while select_not_mastered_question: # make sures the next question has not already been mastered
if mastery[q_no] == 3:
if q_no == max_q_no:
q_no = 0
q_no += 1
else:
select_not_mastered_question = False
window['-OUTPUT-'].update(question[q_no]) # accepts the answer as correct and moves onto the next question
window['-OUTPUTA-'].update('')
window['-OUTPUTB-'].update('')
window['-OUTPUTC-'].update('')
already_correct = True
if any(answer in values['-INPUT-'].lower() for answer in automark[q_no]): # shows the answer was correct but missing some key points
if already_correct:
return
else:
window['-OUTPUTA-'].update(answers[q_no])
window['-OUTPUTB-'].update(markscheme[q_no])
window['-OUTPUTC-'].update('partially correct')
window['-INPUT-'].update(disabled=True)
window['b1'].update(disabled=True)
window['b1'].update(bind_return_key=False)
if event == 'Skip':
q_no += 1
if q_no == max_q_no:
q_no = 0
while select_not_mastered_question: # make sures the next question has not already been mastered
if mastery[q_no] == 3:
if q_no == max_q_no:
q_no = 0
q_no += 1
else:
select_not_mastered_question = False
window['-OUTPUT-'].update(question[q_no]) # moves onto the next question
window['-OUTPUTA-'].update('')
window['-OUTPUTB-'].update('')
window['-OUTPUTC-'].update('')
window['-INPUT-'].update(disabled=False)
window['b1'].update(disabled=False)
window['b1'].update(bind_return_key=True)
elif values['-INPUT-'] == '':
print('answer was:', answers[q_no]) # for testing
window['-OUTPUTA-'].update(
answers[q_no]) # shows that the answer is incorrect and displays the right answer
window['-OUTPUTB-'].update(markscheme[q_no])
window['-OUTPUTC-'].update('incorrect')
window['-INPUT-'].update(disabled=True)
window['b1'].update(disabled=True)
window['b1'].update(bind_return_key=False)
incorrect[q_no] += 1
if mastery[q_no] == 0:
print(mastery)
else:
mastery[q_no] -= 1
print(mastery)
window.close()
main()
这是 PySimpleGUI 中的 issue 2548。
从 4.16.0 版开始,还有一个快捷方式可以从元素中解除键的绑定:
I've also added an Element.unbind
method to match the Element.bind
method. This will allow you to unbind tkinter events from an element without needing to access the element's Widget member variable.
因此您可以使用以下方法从您的元素(不是按钮)中取消绑定 tkinter 的 return 按键事件('<Return>'
) (使用键 b1
)但输入(使用键 -INPUT-
的文本字段):
# window['b1'].update(bind_return_key=False) # raises error
window['-INPUT-'].unbind('<Return>')
类似地,您可以通过以下方式将 return 键绑定到文本输入:
# window['b1'].update(bind_return_key=True) # raises your error
window['-INPUT-'].bind('<Return>', None) # bind just the return key with no modifiers
另见 PySimpleGUI 的调用参考:
要启用和禁用绑定到 return 键功能,您只需更改按钮中的成员变量即可。
tkinter 级别的“绑定”不在按钮上,因此从按钮解除绑定不会产生影响。
在我的 意见 中,最简单的方法是检查如果检测到按钮要做什么。您可以采取行动,也可以忽略它。与其依赖按钮的设置,不如依赖代码中的设置,即您处于应该忽略它的“状态”。我假设用户也可以单击您的按钮。
您收到的错误仅仅是因为您使用错误的参数调用更新。查看有效列表的调用参考,或查看文档字符串。
如果你确实想要enabled/disable绑定return键,那么你可以使用成员变量Button.BindReturnKey
。当按下 Return 时,将此标志设置为 True 的第一个按钮将是 returned 给你的。
这是进行变量操作的示例代码。
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Text(size=(20,1), key='-OUT-')],
[sg.Button('Go1', bind_return_key=True), sg.B('Go2'), sg.B('Switch to Go2'), sg.B('Disable')] ]
window = sg.Window('Bind Return Key', layout)
while True:
event, values = window.read()
window['-OUT-'].update(f'{event, values}')
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Switch to Go2':
window['Go1'].BindReturnKey = False
window['Go2'].BindReturnKey = True
elif event == 'Disable':
window['Go1'].BindReturnKey = window['Go2'].BindReturnKey = False
window.close()
这是它的样子....
我需要在问题回答错误后将 bind_return_key 参数禁用为 false。该参数绑定到 'b1' 键下的提交按钮。我使用了 .update() 方法,它在一周前就开始工作了。它不再有效,我收到此错误:“TypeError: update() 有一个意外的关键字参数 'bind_return_key'”
有解决办法吗?
我尝试过的事情:
- 将要更新的内容从键 'b1' 更改为 'Submit'
- 打开了一个新的项目文件来安装我认为是 4.55.1 的最新版本
import PySimpleGUI as sg
import json
data = {
"question": [
"Q1. What is the equation for force",
"Q2. Define isotope",
"Q3. Define wavelength",
"Q4. Define modal dispersion"
],
"answers": [
"f=ma",
"isotopes are atoms of the same element but with a different number of neutrons",
"the least distance between adjacent particles which are in phase",
"causes light travelling at different angles to arrive at different times"
],
"automark": [
["force=massxacceleration"],
["same number of protons", "different number of neutrons", "same element"],
["minimum distance between adjacent particles", "particles which are in phase"],
["different angles", "different times"]
],
"markscheme": [
["force=massxacceleration"],
["same number of protons", "different number of neutrons", "same element"],
["minimum distance between adjacent particles", "particles which are in phase"],
["different angles", "different times"]
],
"mastery": [
0,
0,
0,
0
],
"incorrect": [
0,
0,
0,
0
]
}
def nextset(no, no2, do_not_stop, list1, list2):
endlist = [] # number in the list represent question number
while not do_not_stop:
if no == 3:
do_not_stop = True
if list2[no] == list1[no2]:
position = list1.index(list2[no])
no += 1
no2 = 0
endlist.append(position)
print(endlist)
else:
no2 += 1
savetoexternal(endlist)
def savetoexternal(endlist):
with open("savefile.json", 'w') as f: # creates external json file to be read from later
json.dump(endlist, f, indent=2)
# main program
def listdata(list1):
do_not_stop = False
no = 0
no2 = 0
list2 = list1.copy()
list2.sort(
reverse=True) # ordered question from highest to lowest while keeping original intact to preserve question number
print(list1)
print(list2)
nextset(no, no2, do_not_stop, list1, list2)
def main():
# initialise the question, question number and answer
question = data['question']
answers = data['answers']
automark = data['automark']
markscheme = data['markscheme']
mastery = data['mastery']
incorrect = data['incorrect']
q_no = 0
max_q_no = 4
sg.theme('DarkBlack') # Adding colour
# Stuff in side the window
layout = [[sg.Text(" "), sg.Text(question[0], key='_Q1_', visible=True),
sg.Text(size=(60, 1), key='-OUTPUT-')],
[sg.Text("correct answer:"), sg.Text(size=(60, 1), key='-OUTPUTA-')],
[sg.Text("automark allows:"), sg.Text(size=(60, 1), key='-OUTPUTB-')],
[sg.Text("your answer was:"), sg.Text(size=(60, 1), key='-OUTPUTC-')],
[sg.Text('Answer here: '), sg.InputText(size=(60, 1), key='-INPUT-', do_not_clear=False)],
[sg.Button('Submit', key='b1', bind_return_key=True), sg.Button('Cancel'), sg.Button('Skip')]]
# Create the Window
window = sg.Window('Rerevise', layout, size=(655, 565))
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel
break
window['_Q1_'].Update(visible=False)
window['-OUTPUT-'].update(question[q_no])
select_not_mastered_question = True
already_correct = False
if all(x == 3 for x in mastery):
print("all questions mastered") # add to gui later
list1 = []
q_no = 0
while q_no < max_q_no:
list1.append(incorrect[q_no])
q_no += 1
q_no = 0
listdata(list1)
if values['-INPUT-'].lower() == answers[q_no]: # list index out of range occurs when all questions are complete, need to add completed screen by using else statement
mastery[q_no] += 1 # need to add to gui
print(mastery)
q_no += 1
if q_no == max_q_no:
q_no = 0
while select_not_mastered_question: # make sures the next question has not already been mastered
if mastery[q_no] == 3:
if q_no == max_q_no:
q_no = 0
q_no += 1
else:
select_not_mastered_question = False
window['-OUTPUT-'].update(question[q_no]) # accepts the answer as correct and moves onto the next question
window['-OUTPUTA-'].update('')
window['-OUTPUTB-'].update('')
window['-OUTPUTC-'].update('')
if all(answer in values['-INPUT-'].lower() for answer in automark[q_no]):
print(automark[q_no])
mastery[q_no] += 1 # need to add to gui
print(mastery)
q_no += 1
if q_no == max_q_no:
q_no = 0
while select_not_mastered_question: # make sures the next question has not already been mastered
if mastery[q_no] == 3:
if q_no == max_q_no:
q_no = 0
q_no += 1
else:
select_not_mastered_question = False
window['-OUTPUT-'].update(question[q_no]) # accepts the answer as correct and moves onto the next question
window['-OUTPUTA-'].update('')
window['-OUTPUTB-'].update('')
window['-OUTPUTC-'].update('')
already_correct = True
if any(answer in values['-INPUT-'].lower() for answer in automark[q_no]): # shows the answer was correct but missing some key points
if already_correct:
return
else:
window['-OUTPUTA-'].update(answers[q_no])
window['-OUTPUTB-'].update(markscheme[q_no])
window['-OUTPUTC-'].update('partially correct')
window['-INPUT-'].update(disabled=True)
window['b1'].update(disabled=True)
window['b1'].update(bind_return_key=False)
if event == 'Skip':
q_no += 1
if q_no == max_q_no:
q_no = 0
while select_not_mastered_question: # make sures the next question has not already been mastered
if mastery[q_no] == 3:
if q_no == max_q_no:
q_no = 0
q_no += 1
else:
select_not_mastered_question = False
window['-OUTPUT-'].update(question[q_no]) # moves onto the next question
window['-OUTPUTA-'].update('')
window['-OUTPUTB-'].update('')
window['-OUTPUTC-'].update('')
window['-INPUT-'].update(disabled=False)
window['b1'].update(disabled=False)
window['b1'].update(bind_return_key=True)
elif values['-INPUT-'] == '':
print('answer was:', answers[q_no]) # for testing
window['-OUTPUTA-'].update(
answers[q_no]) # shows that the answer is incorrect and displays the right answer
window['-OUTPUTB-'].update(markscheme[q_no])
window['-OUTPUTC-'].update('incorrect')
window['-INPUT-'].update(disabled=True)
window['b1'].update(disabled=True)
window['b1'].update(bind_return_key=False)
incorrect[q_no] += 1
if mastery[q_no] == 0:
print(mastery)
else:
mastery[q_no] -= 1
print(mastery)
window.close()
main()
这是 PySimpleGUI 中的 issue 2548。
从 4.16.0 版开始,还有一个快捷方式可以从元素中解除键的绑定:
I've also added an
Element.unbind
method to match theElement.bind
method. This will allow you to unbind tkinter events from an element without needing to access the element's Widget member variable.
因此您可以使用以下方法从您的元素(不是按钮)中取消绑定 tkinter 的 return 按键事件('<Return>'
) (使用键 b1
)但输入(使用键 -INPUT-
的文本字段):
# window['b1'].update(bind_return_key=False) # raises error
window['-INPUT-'].unbind('<Return>')
类似地,您可以通过以下方式将 return 键绑定到文本输入:
# window['b1'].update(bind_return_key=True) # raises your error
window['-INPUT-'].bind('<Return>', None) # bind just the return key with no modifiers
另见 PySimpleGUI 的调用参考:
要启用和禁用绑定到 return 键功能,您只需更改按钮中的成员变量即可。
tkinter 级别的“绑定”不在按钮上,因此从按钮解除绑定不会产生影响。
在我的 意见 中,最简单的方法是检查如果检测到按钮要做什么。您可以采取行动,也可以忽略它。与其依赖按钮的设置,不如依赖代码中的设置,即您处于应该忽略它的“状态”。我假设用户也可以单击您的按钮。
您收到的错误仅仅是因为您使用错误的参数调用更新。查看有效列表的调用参考,或查看文档字符串。
如果你确实想要enabled/disable绑定return键,那么你可以使用成员变量Button.BindReturnKey
。当按下 Return 时,将此标志设置为 True 的第一个按钮将是 returned 给你的。
这是进行变量操作的示例代码。
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-')],
[sg.Text(size=(20,1), key='-OUT-')],
[sg.Button('Go1', bind_return_key=True), sg.B('Go2'), sg.B('Switch to Go2'), sg.B('Disable')] ]
window = sg.Window('Bind Return Key', layout)
while True:
event, values = window.read()
window['-OUT-'].update(f'{event, values}')
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Switch to Go2':
window['Go1'].BindReturnKey = False
window['Go2'].BindReturnKey = True
elif event == 'Disable':
window['Go1'].BindReturnKey = window['Go2'].BindReturnKey = False
window.close()
这是它的样子....