简体   繁体   中英

How can I disable the return_bind_key in PySimpleGui?

I need to disable the bind_return_key parameter to false after a question is answered incorrectly. The parameter is binded to the submit button under the key 'b1'. I used the.update() method and it worked around a week ago. It not longer works and I receive this error: "TypeError: update() got an unexpected keyword argument 'bind_return_key'"

Is there a fix to this?

Things I've tried:

  • changed what is being updated from key 'b1' to 'Submit'
  • opened a new project file to install the newest version which I think is 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()

This was an issue 2548 in PySimpleGUI.

Since version 4.16.0 there is also a shortcut to unbind a key from an element:

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.

Thus you can use following to unbind Return key-press events from your b1 element:

window['b1'].unbind('<Return>')

To both enable and disable the bind to return key feature, you can simply change a member variable in your buttons.

The "Bind" at the tkinter level is not on the button, so unbinding from the button won't have an impact.

In my opinion , the simplest approach is to check what to do if the button is detected.. you can take action, or ignore it. Rather than relying on the button's setting, rely on a setting in your code that you're in a "state" where it should be ignored. The user will be able to CLICK your button too I assume.

The error your getting is simply because you're calling update with the wrong parms. See the call ref for the valid list, or look at the docstring.

If you really want to enabled/disable the binding of the return key, then you can use the member variable Button.BindReturnKey . The first button that has this flag set to True will be what's returned to you when Return is pressed.

Here's example code for doing variable manipulations.

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

This is how it looks....

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM