Как изменить дату при нажатии кнопки?

У меня есть окно tkinker с кнопками date и choose date, которое я называю домашней страницей. Когда пользователь выбирает дату, я хочу, чтобы дата обновлялась на домашней странице. Я перенастроил выбранную дату в функции datecheck. Затем я хочу обновить дату домашней страницы с датой возврата. Я не знаю, как сделать это возможным. Помогите мне с каким-нибудь решением.

Вот пример кода, который я написал:

from tkinter import *
from tkinter import ttk
from tkinter import scrolledtext
import time
import tkinter.messagebox
from datetime import datetime
import tkinter as tk
import sys
import os
from tkcalendar import Calendar, DateEntry
from datetime import date
import multiprocessing


def datecheck():
    global date_string
    root = Tk()
    s = ttk.Style(root)
    s.theme_use('clam')
    def print_sel():
        global date_string,timestamp
        date_string =cal.selection_get()
        date_string=date_string.strftime("%d-%b-%Y")
        print("returned_date",date_string)
        root.destroy()
    today = date.today()
    d = int(today.strftime("%d"))
    m= int(today.strftime("%m"))
    y =int(today.strftime("%Y"))
    cal = Calendar(root,
                   font="Arial 14", selectmode='day',
                   cursor="hand1",   day=d,month=m,year=y)
    cal.pack(fill="both", expand=True)
    ttk.Button(root, text="ok", command=print_sel).pack()
def homepage():
    global date_string,timestamp
    if date_string == "":
            timestamp = datetime.now().strftime("%d-%b-%Y")

    else:
        timestamp = date_string
    def close_window():
        window.destroy()

    window = Tk()
    window.title("Status Uploader")
    window.geometry('500x200')
    Label(window,
          text="Status Uploader",
          fg="blue",
          bg="yellow",
          font="Verdana 10 bold").pack()
    Label(window,
          text="Date : {}".format(timestamp),
          fg="red",
          bg="yellow",
          font="Verdana 10 bold").pack()

    txt = scrolledtext.ScrolledText(window, width=60, height=9.5)
    txt.pack()
    button = Button(window, fg='white', bg='blue',
                    text="Choose Date", command=datecheck)
    button.place(x=35, y=152)
    button = Button(window, fg='white', bg='red',
                    text="Close", command=close_window)
    button.place(x=405, y=152)
    window.mainloop()        

global date_string,timestamp
date_string = ""
homepage()

Скриншот:

скриншот запуска скрипта


person crust salty    schedule 27.09.2019    source источник
comment
Что вы сделали, чтобы отладить это? Вы проверили, что другой процесс запускается? Вы убедились, что действительно меняете datestring? Знаете ли вы, что простое изменение timestamp ничего не изменит на дисплее?   -  person Bryan Oakley    schedule 27.09.2019
comment
Да, распространенный способ делать другие вещи во время работы mainloop() tkinter (который должен вызываться, чтобы графический интерфейс мог обрабатывать пользовательские события) — это использовать универсальный виджет after() для планирования периодических вызовов к функции.   -  person martineau    schedule 27.09.2019
comment
@Bryan Oakley, да, два процесса начинаются.   -  person crust salty    schedule 27.09.2019
comment
@crustsalty: удалите все, что связано с multiprocessing, и следуйте этому шаблону виджет календаря python - возвращает выбранную пользователем дату   -  person stovfl    schedule 27.09.2019
comment
@Bryan Oakley, я удалил многопроцессорность и вернул дату. Я обновил код. После этого как обновить homepage date с моим returned_date   -  person crust salty    schedule 27.09.2019
comment
@crustsalty: Вам действительно нужно собственное окно datecheck()? У вас есть два = Tk(), у вас должен быть только один. Rarad Почему использование нескольких экземпляров Tk не рекомендуется?   -  person stovfl    schedule 27.09.2019


Ответы (1)


Вот версия вашего кода, которая не использует multiprocessing, потому что я не думаю, что ее использование необходимо, хотя я действительно не понимаю, что вы пытаетесь сделать с двумя глобальными переменными date_string и timestamp и как они относятся друг к другу. Все, что происходит в приведенном ниже коде, это то, что последний периодически копируется в первый функцией fun(), которая вызывается каждые 1000 миллисекунд (например, один раз в секунду).

Это делается с помощью универсального виджета tkinter after{}, чтобы периодически проверять дату и время и обновлять глобальные переменные — в этом случае multiprocessing делать этого не требуется.

Чтобы метка, показывающая дату, менялась после того, как пользователь выбрал новую дату, я добавил параметр date_label в функцию datecheck() и изменил функцию homepage(), чтобы передать ее в качестве аргумента функции, когда она вызывается нажатием на < kbd>Выберите дату Button.

Я также в целом почистил код и привел его в соответствие с PEP 8 — Руководство по стилю для Python. Руководства по коду, чтобы их было легче читать и поддерживать.

from datetime import date, datetime
from functools import partial
import os
import sys
from tkcalendar import Calendar, DateEntry
from tkinter import ttk
from tkinter import scrolledtext
import tkinter as tk

def datecheck(date_label):
    global date_string, timestamp

    root = tk.Toplevel()
    s = ttk.Style(root)
    s.theme_use('clam')

    def print_sel():
        global date_string

        cal_selection = cal.selection_get()
        date_string = cal_selection.strftime("%d-%b-%Y")
        # Update the text on the date label.
        date_label.configure(text="Date : {}".format(date_string))
        root.destroy()

    today = date.today()
    d = int(today.strftime("%d"))
    m = int(today.strftime("%m"))
    y =int(today.strftime("%Y"))

    cal = Calendar(root,
                   font="Arial 14", selectmode='day',
                   cursor="hand1", day=d,month=m, year=y)
    cal.pack(fill="both", expand=True)

    ttk.Button(root, text="ok", command=print_sel).pack()


def homepage():
    global date_string, timestamp

    if date_string == "":
        timestamp = datetime.now().strftime("%d-%b-%Y")
    else:
        timestamp = date_string

    def close_window():
        window.destroy()

    window = tk.Tk()
    window.title("Status Uploader")
    window.geometry('500x200')
    tk.Label(window,
             text="Status Uploader",
             fg="blue",
             bg="yellow",
             font="Verdana 10 bold").pack()
    date_label = tk.Label(window,
                          text="Date : {}".format(timestamp),
                          fg="red",
                          bg="yellow",
                          font="Verdana 10 bold")
    date_label.pack()

    # Create callback function for "Choose Date" Button with data_label
    # positional argument automatically supplied to datecheck() function.
    datecheck_callback = partial(datecheck, date_label)

    txt = scrolledtext.ScrolledText(window, width=60, height=9.5)
    txt.pack()

    button = tk.Button(window, fg='white', bg='blue',
                       text="Choose Date",
                       command=datecheck_callback)
    button.place(x=35, y=152)
    button = tk.Button(window, fg='white', bg='red', text="Close", command=close_window)
    button.place(x=405, y=152)

    window.after(1000, fun, window)  # Start periodic global variable updates.
    window.mainloop()


def fun(window):
    """ Updates some global time and date variables. """
    global date_string, timestamp

    if date_string == "":
        timestamp = datetime.now().strftime("%d-%b-%Y")
    else:
        timestamp = date_string

    window.after(1000, fun, window)  # Check again in 1000 milliseconds.


# Define globals.
date_string = ""
timestamp = None

homepage() # Run GUI application.
person martineau    schedule 27.09.2019
comment
корка соленая: рад слышать, что это помогло. Программирование tkinter может быть довольно сложным, потому что оно так плохо документировано и во многих отношениях не является pythonic, плюс у него есть много правил, и необходимо изучить определенное количество приемов, чтобы наилучшим образом использовать его — так что это может быть не так. самый быстрый способ изучения основ языка Python. Несмотря на это, наличие некоторых из них, которые теперь работают так, чтобы играть, должно пройти долгий путь в освоении этого. Желаем удачи в ваших начинаниях. - person martineau; 28.09.2019