Комбинированная функция ввода Tkinter и кнопки не работает в другой функции

#python #tkinter #tk

#python #tkinter #tk-toolkit

Вопрос:

Я создал функцию, вызывающую графический интерфейс, содержащий несколько записей и кнопку. Если я нажму кнопку, то значения для записей будут возвращены функцией.

 def date_time_gui ():
    win = tk.Tk()
    win.title('powered by Python') # win title
    win.geometry('700x400') # size of win

    # add label on the win
    label = tk.Label(win, 
        text='type the heaving datetime and out water datetime',
        font = ('Arial Bold',25)
        )
    label.place(relx = 0.5, rely = 0.05, anchor = 'n')

    # label and entry for heaving datetime
    heaving_label = tk.Label(win,
        text='type heaving datetime',
        font = ('Arial Bold', 15)
        )
    heaving_label.place(relx = 0.1, rely = 0.3, anchor = 'w')

    h_year_label = tk.Label(win, text='YEAR (4 digits) :')
    h_year_label.place(relx = 0.1, rely = 0.4, anchor = 'w')
    h_year = tk.Entry(win, fg='black', width = 5)
    h_year.place(relx = 0.3, rely = 0.4, anchor = 'w')


    h_month_label = tk.Label(win, text='MONTH (2 digits) :')
    h_month_label.place(relx = 0.1, rely = 0.5, anchor = 'w')
    h_month = tk.Entry(win, fg='black', width = 5)
    h_month.place(relx = 0.3, rely = 0.5, anchor = 'w')


    h_date_label = tk.Label(win, text='DATE (2 digits) :')
    h_date_label.place(relx = 0.1, rely = 0.6, anchor = 'w')
    h_date = tk.Entry(win, fg='black', width = 5)
    h_date.place(relx = 0.3, rely = 0.6, anchor = 'w')


    h_hour_label = tk.Label(win, text='HOUR (24h, 2 digits) :')
    h_hour_label.place(relx = 0.1, rely = 0.7, anchor = 'w')
    h_hour = tk.Entry(win, fg='black', width = 5)
    h_hour.place(relx = 0.3, rely = 0.7, anchor = 'w')

    h_minute_label = tk.Label(win, text='MINUTE (2 digits) :')
    h_minute_label.place(relx = 0.1, rely = 0.8, anchor = 'w')
    h_minute = tk.Entry(win, fg='black', width = 5)
    h_minute.place(relx = 0.3, rely = 0.8, anchor = 'w')



    # label and entry for out water datetime
    outwater_label = tk.Label(win,
        text='type out water datetime',
        font = ('Arial Bold', 15)
        )
    outwater_label.place(relx = 0.5, rely = 0.3, anchor = 'w')

    o_year_label = tk.Label(win, text='YEAR (4 digits) :')
    o_year_label.place(relx = 0.5, rely = 0.4, anchor = 'w')
    o_year = tk.Entry(win, fg='black', width = 5)
    o_year.place(relx = 0.7, rely = 0.4, anchor = 'w')


    o_month_label = tk.Label(win, text='MONTH (2 digits) :')
    o_month_label.place(relx = 0.5, rely = 0.5, anchor = 'w')
    o_month = tk.Entry(win, fg='black', width = 5)
    o_month.place(relx = 0.7, rely = 0.5, anchor = 'w')


    o_date_label = tk.Label(win, text='DATE (2 digits) :')
    o_date_label.place(relx = 0.5, rely = 0.6, anchor = 'w')
    o_date = tk.Entry(win, fg='black', width = 5)
    o_date.place(relx = 0.7, rely = 0.6, anchor = 'w')


    o_hour_label = tk.Label(win, text='HOUR (24h, 2 digits) :')
    o_hour_label.place(relx = 0.5, rely = 0.7, anchor = 'w')
    o_hour = tk.Entry(win, fg='black', width = 5)
    o_hour.place(relx = 0.7, rely = 0.7, anchor = 'w')

    o_minute_label = tk.Label(win, text='MINUTE (2 digits) :')
    o_minute_label.place(relx = 0.5, rely = 0.8, anchor = 'w')
    o_minute = tk.Entry(win, fg='black', width = 5)
    o_minute.place(relx = 0.7, rely = 0.8, anchor = 'w')

    def run_func ():
        global heaving
        global outwater
        heaving = h_year.get() '.' h_month.get() '.' h_date.get() ' ' h_hour.get() ' ' h_minute.get()
        outwater = o_year.get() '.' o_month.get() '.' o_date.get() ' ' o_hour.get() ' ' o_minute.get()
        print('here')
        win.destroy()
        print('there')
        return heaving, outwater
    print('else')
    button = ttk.Button(win, text = 'run', command = run_func)  
    button.place(relx = 0.8, rely = 0.9, anchor = 'w')
    print('this')
    win.mainloop()
    print('where')
    return heaving, outwater
  

Она работает, если я запускаю ее со следующим кодом в том же скрипте.

 if __name__ == "__main__":
    h, o = date_time_gui()
    print(h,o)
  

он распечатал h, o, которые являются возвращаемыми значениями функции date_time_gui

Однако, если я применю эту функцию к другому определению, например

 def other_def():
    ## some code
    heaving_datetime, out_water_datetime = date_time_gui()
  

Она просто перестает работать.

Я хотел проверить, в какой строке date_time_gui проблема, поэтому я напечатал «там», «где» и т.д.

Когда я запускаю other_def, он распечатывает еще вот это здесь

а потом не напечатал «где».

Я действительно не знаю, в чем проблема, поскольку сама функция date_time_gui работает хорошо. Это не работает, когда я применяю это к другим функциям.

  • возможно, для запуска other_def я создал графический интерфейс с флажком для запуска other_def. Итак, если я проверю функцию other_def в графическом интерфейсе и нажму кнопку run, графический интерфейс будет уничтожен, а other_def будет запущен. И новый графический интерфейс для всплывающего окна date_time_gui и нажатия кнопки run, затем графический интерфейс уничтожен и перестает работать.

Комментарии:

1. Вы сказали «это просто перестает работать». Что это значит? Происходит ли сбой программы? Вы получаете исключение?

2. если он не выводит «где», это должно означать, что mainloop() все еще выполняется и графический интерфейс не завершился.

Ответ №1:

При использовании окна tkinter

  • Вызов метода loop() активирует перекачку сообщений tkinter и остановит линейный код python до тех пор, пока окно не будет закрыто
  • Вы можете выйти из цикла, вручную закрыв окно или вызвав quit() из своего кода.

В вашем случае вызов win.mainloop() остановил линейный скрипт.

Вы можете выйти из цикла, добавив win.quit() в run_func функцию.

Попробуйте этот код:

     def run_func ():
        global heaving
        global outwater
        heaving = h_year.get() '.' h_month.get() '.' h_date.get() ' ' h_hour.get() ' ' h_minute.get()
        outwater = o_year.get() '.' o_month.get() '.' o_date.get() ' ' o_hour.get() ' ' o_minute.get()
        print('here')
        win.destroy()
        print('there')
        win.quit()   # exit gui loop
        return heaving, outwater  # not needed
    
    print('else')
    button = ttk.Button(win, text = 'run', command = run_func)  
    button.place(relx = 0.8, rely = 0.9, anchor = 'w')
    print('this')
    win.mainloop()  # python code stops here until window closed
    print('where')
    heaving, outwater = 3,4  # for testing
    return heaving, outwater

if __name__ == "__main__":
    h, o = date_time_gui()
    print(h,o)
  

Вывод

 else
this
here
there
where
3 4