Tkinter SimpleDialog Тайм-аут - PullRequest
       19

Tkinter SimpleDialog Тайм-аут

0 голосов
/ 28 октября 2019

У меня есть программа, которая требует ввода в модуль во время его работы, поэтому я реализую простое диалоговое окно для получения ввода от пользователя для использования в моей программе Tkinter. Но мне также нужен таймаут при запуске модуля в виде консольной программы, чтобы пропустить его или тайм-аут после стольких секунд, когда пользователь не взаимодействует с ним. И не иметь его просто сидеть и ждать вечно, пока пользователь не взаимодействует с ним. Как мне закрыть окно после тайм-аута? Вот что у меня сейчас ...


def loginTimeout(timeout=300):
    root = tkinter.Tk()
    root.withdraw()
    start_time = time.time()
    input1 = simpledialog.askinteger('Sample','Enter a Number')
    while True:
        if msvcrt.kbhit():
            chr = msvcrt.getche()
            if ord(chr) == 13: # enter_key
                break
            elif ord(chr) >= 32: #space_char
                input1 += chr
        if len(input1) == 0 and (time.time() - start_time) > timeout:
            break

    print('')  # needed to move to next line
    if len(input1) > 0:
        return input1
    else:
        return input1

1 Ответ

0 голосов
/ 28 октября 2019

Не совсем уверен, в чем вопрос, но вы можете использовать метод tkinter after() аналогично этому:

import tkinter as tk

root = tk.Tk()
root.geometry('100x100')

def get_entry() -> str:
    """Gets and returns the entry input, and closes the tkinter window."""
    entry = entry_var.get()
    root.destroy() # Edit: Changed from root.quit()
    return entry

# Your input box
entry_var = tk.StringVar()
tk.Entry(root, textvariable=entry_var).pack()

# A button, or could be an event binding that triggers get_entry()
tk.Button(root, text='Enter/Confirm', command=get_entry).pack()

# This would be the 'timeout'
root.after(5000, get_entry)

root.mainloop()

Итак, если пользователь вводит что-то, он может нажать подтвердить или запуститьсобытие, привязанное к записи, или после задержки программа все равно запускает get_entry. Может быть, это даст вам представление, вы также можете проверить другие методы виджетов: https://effbot.org/tkinterbook/widget.htm

РЕДАКТИРОВАТЬ: я не уверен, как это устроено в вашей программе, но root.mainloop() блоков, поэтому один разон работает, код после того, как он не будет работать до выхода из mainloop (). Если ваша функция является частью окна верхнего уровня (), вы можете использовать wait_window(), чтобы предотвратить продвижение функции до тех пор, пока ваш тайм-аут не разрушит окно верхнего уровня или функция не будет вызвана ранее пользователем. Пример, хотя, возможно, и не лучшее решение, будет:

def loginTimeout(timeout_ms: int=5000):
    root = tk.Tk()
    root.geometry('200x50')

    # function to get input and change the function variable
    input_ = ''
    def get_input():
        nonlocal input_
        input_ = entry_var.get()
        root.destroy()

    # build the widgets
    entry_var = tk.StringVar()
    tk.Entry(root, textvariable=entry_var).pack(side='left')
    tk.Button(root, text='Confirm', command=get_input).pack(side='right')

    # timeout
    root.after(timeout_ms, get_input)

    # mainloop
    root.mainloop()

    # won't get here until root is destroyed
    return input_

print(loginTimeout())
...