如何禁用 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'”

有解决办法吗?

我尝试过的事情:

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()

这是它的样子....