#python #tkinter
Вопрос:
В моей программе на Python я определил такую функцию:
def engine_input_number_of_students_and_student_information(self, window):
self.__input.input_number_of_students(self, window)
print(self.number_of_students)
и функция input_number_of_students
была определена во входных данных класса следующим образом:
class Input:
# Function to ask user to input number of student.
# Print error and force the user to re-input if wrong data is given.
def input_number_of_students(self, engine, window):
sub = tk.Toplevel(master=window)
sub.title("Number of students")
sub.resizable(height=False, width=False)
window.eval(f'tk::PlaceWindow {str(sub)} center')
frm1 = tk.Frame(master=sub)
frm1.grid(row=0, column=0, padx=10, pady=10)
lbl = tk.Label(text="Enter number of students:", master=frm1)
number_of_students_var = tk.StringVar()
ent = tk.Entry(width=3, master=frm1, textvariable=number_of_students_var)
lbl.grid(row=0, column=0, padx=5)
ent.grid(row=0, column=1, padx=5)
frm2 = tk.Frame(master=sub)
frm2.grid(row=1, column=0, sticky="nsew", padx=5, pady=5)
def ok():
number_of_students = int(number_of_students_var.get())
if number_of_students < 0:
messagebox.showinfo(message="Error: number of students must be non-negative")
ent.delete(-1, tk.END)
else:
engine.number_of_students = number_of_students
print(engine.number_of_students)
sub.destroy()
ok_btn = tk.Button(text="OK", master=frm2, command=ok)
ok_btn.pack(ipadx=5, ipady=5)
Но когда я пытаюсь протестировать программу, print
функция была выполнена, даже когда я ничего не вводил для number_of_students
(очевидно, она выводит 0). И я не знаю, почему.
Комментарии:
1. Итак, ваш реальный вопрос заключается в том, как вы зависаете,
input_number_of_students()
пока кто-то не нажмет кнопку и не введет несколько студентов?2. Попробуй
print(message, flush=True)
. Дело не в том, чтобы «ждать», а в том, чтобы перейти на stdout3. Я пытался дождаться, пока пользователь введет значение, а затем это значение будет напечатано. Например, когда я ввожу «2» в запись, а затем нажимаю «ОК», после этого будет выведено 2, но
4. О, я понял свою проблему. Проблема в том, что
input_number_of_students
создано только подокно, и считается выполненным после этого, а не после нажатия «ОК». Что я хотел бы сделать, так это то, что функция будет выполнена после того, как я введу некоторое значение и нажму «ОК».5. @GreenCloakGuy да, это то, что я пытаюсь сделать
Ответ №1:
Ваш input_number_of_students
не ждет ввода пользователем, он создает окно tkinter, поле ввода и кнопку, но нигде не ждет, пока пользователь что-то введет. Таким образом, программа переходит к следующей строке, которая является print
строкой, и выводит a 0
.
Чтобы исправить это, вам нужно позвонить print
из функции обратного ok
вызова или использовать wait_variable
ключевое слово.
class Input:
# Function to ask user to input number of student.
# Print error and force the user to re-input if wrong data is given.
def input_number_of_students(self, engine, window):
sub = tk.Toplevel(master=window)
sub.title("Number of students")
sub.resizable(height=False, width=False)
window.eval(f'tk::PlaceWindow {str(sub)} center')
frm1 = tk.Frame(master=sub)
frm1.grid(row=0, column=0, padx=10, pady=10)
lbl = tk.Label(text="Enter number of students:", master=frm1)
number_of_students_var = tk.StringVar()
ent = tk.Entry(width=3, master=frm1, textvariable=number_of_students_var)
lbl.grid(row=0, column=0, padx=5)
ent.grid(row=0, column=1, padx=5)
frm2 = tk.Frame(master=sub)
frm2.grid(row=1, column=0, sticky="nsew", padx=5, pady=5)
def ok():
number_of_students = int(number_of_students_var.get())
if number_of_students < 0:
messagebox.showinfo(message="Error: number of students must be non-negative")
ent.delete(-1, tk.END)
else:
engine.number_of_students = number_of_students
print(engine.number_of_students)
sub.destroy()
ok_btn = tk.Button(text="OK", master=frm2, command=ok)
ok_btn.pack(ipadx=5, ipady=5)
#I'm guessing this is the variable you modify?
ok_btn.wait_variable(engine.number_of_students_var)
Комментарии:
1. О, это хорошо сработало
wait_variable
. Переменная, которую я хочу изменить, таковаengine.number_of_students
. Большое спасибо!2. Использование
wait_variable
в этом случае не работает, если пользователь закрывает верхний уровень с помощью кнопки «Закрыть» в строке заголовка, ничего не вводя. Лучше использоватьwait_window()
вместо этого.