Календарь событий перезаписывает недели - PullRequest
0 голосов
/ 23 марта 2020

Я пытаюсь создать календарь, который позволяет вам видеть, когда у вас есть событие. События читаются из встречи.txt

Пример Содержание встречи.txt

Sally Banks,11/3/2020,2:45
Sally Banks,20/3/2020,2:45
Sally Banks,21/3/2020,2:45

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

Ожидаемый результат

Я хочу, чтобы выведенный календарь имел красный цвет кнопка, если с датой, с которой она связана, назначена встреча. Например,

expected

Фактический вывод

Я очень близок к тому, чтобы заставить это работать, используя этот код :

for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
    #If appointment on
    for dayInt,monthInt,yearInt in appointments:
        #Is their an appointment this week?
        appWeek = False

        #There is an appointment this week
        if (int(dayInt) in week) and int(monthInt)==m and int(yearInt) ==y:
            appWeek=True
            bookedDays.append(int(dayInt))
            print(bookedDays)
            for d, day in enumerate(week):
                if day in bookedDays:
                    b = tk.Button(self.parent, width=1, bg="red", text=day,
                                  command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                    self.wid.append(b)
                    b.grid(row=w, column=d)
                else :
                    # print(calendar.day_name[day])
                    b = tk.Button(self.parent, width=1,bg=self.COLOR_OF_DAY_BUTTONS, text=day,
                                    command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                    self.wid.append(b)
                    b.grid(row=w, column=d)
        #There is an appointment this week, so avoid placing buttons
        elif appWeek == True:
            #Avoid unnecessary re changing of buttons
            pass
        #No appointment so make this line lightblue.
        else:
            #No appointment this week
            for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
                for d, day in enumerate(week):
                    if day:
                        # print(calendar.day_name[day])
                        b = tk.Button(self.parent, width=1, bg=self.COLOR_OF_DAY_BUTTONS, text=day,
                              command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                        self.wid.append(b)
                        b.grid(row=w, column=d)
    # Reset bookedDays in order to allow for multiple appointments on the same day
    bookedDays=[]

Я получаю этот вывод, пустой календарь без красных кнопок

actual output

Однако, если я элиф и прочее Например, например:

for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
    #If appointment on
    for dayInt,monthInt,yearInt in appointments:
        #Appointment this week
        appWeek = False
        if (int(dayInt) in week) and int(monthInt)==m and int(yearInt) ==y:
            appWeek=True
            bookedDays.append(int(dayInt))
            print(bookedDays)
            for d, day in enumerate(week):
                if day in bookedDays:
                    b = tk.Button(self.parent, width=1, bg="red", text=day,
                                  command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                    self.wid.append(b)
                    b.grid(row=w, column=d)
                else :
                    # print(calendar.day_name[day])
                    b = tk.Button(self.parent, width=1,bg=self.COLOR_OF_DAY_BUTTONS, text=day,
                                    command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                    self.wid.append(b)
                    b.grid(row=w, column=d)
        """
        elif appWeek == True:
            #Avoid unnecessary re changing of buttons
            pass
        else:
            #No appointment this week
            for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
                for d, day in enumerate(week):
                    if day:
                        # print(calendar.day_name[day])
                        b = tk.Button(self.parent, width=1, bg=self.COLOR_OF_DAY_BUTTONS, text=day,
                              command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                        self.wid.append(b)
                        b.grid(row=w, column=d)
    # Reset bookedDays in order to allow for multiple appointments on the same day
    bookedDays=[]
    """

Я получаю этот вывод:

actual 2

Как вы можете видеть в этом выводе, я получаю правильные строки для недель, которые назначены, но я не получаю ни одной недели без предварительной записи. Изменение месяца не приводит к появлению новых дней (без кнопок).

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

Весь файл класса Кто-то спросил меня о полном файле класса, поэтому здесь он

import calendar
import datetime
import sys
import csv

# imports correct version of tkinter based on python version
if sys.version[0] == '2':
    import Tkinter as tk
else:
    import tkinter as tk


class CalendarView:
    # Instantiation
    def __init__(self, parent, values):
        self.values = values
        print(values)
        self.parent = parent
        self.cal = calendar.TextCalendar(calendar.SUNDAY)
        self.year = datetime.date.today().year
        self.month = datetime.date.today().month
        self.wid = []
        self.day_selected = 1
        self.month_selected = self.month
        self.year_selected = self.year
        self.day_name = ''
        self.COLOR_OF_CALENDAR_ARROWS = "lightblue"
        self.COLOR_OF_CALENDAR_LABEL = "lightblue"
        self.COLOR_OF_DAY_BUTTONS = "lightblue"

        self.setup(self.year, self.month)

    # Resets the buttons
    def clear(self):
        for w in self.wid[:]:
            w.grid_forget()
            # w.destroy()
            self.wid.remove(w)

    # Moves to previous month/year on calendar
    def go_prev(self):
        if self.month > 1:
            self.month -= 1
        else:
            self.month = 12
            self.year -= 1
        # self.selected = (self.month, self.year)
        self.clear()
        self.setup(self.year, self.month)

    # Moves to next month/year on calendar
    def go_next(self):
        if self.month < 12:
            self.month += 1
        else:
            self.month = 1
            self.year += 1

        # self.selected = (self.month, self.year)
        self.clear()
        self.setup(self.year, self.month)

    # Called on date button press
    def selection(self, day, name):
        self.day_selected = day
        self.month_selected = self.month
        self.year_selected = self.year
        self.day_name = name

        # Obtaining data
        self.values['day_selected'] = day
        self.values['month_selected'] = self.month
        self.values['year_selected'] = self.year
        self.values['day_name'] = name
        self.values['month_name'] = calendar.month_name[self.month_selected]

        self.clear()
        self.setup(self.year, self.month)

    def setup(self, y, m):
        # Tkinter creation
        left = tk.Button(self.parent, text='<', command=self.go_prev,bg=self.COLOR_OF_CALENDAR_ARROWS)
        self.wid.append(left)
        left.grid(row=0, column=1)

        header = tk.Label(self.parent, height=2,bg=self.COLOR_OF_CALENDAR_LABEL, text='{}   {}'.format(calendar.month_abbr[m], str(y)))
        self.wid.append(header)
        header.grid(row=0, column=2, columnspan=3)

        right = tk.Button(self.parent, text='>', command=self.go_next,bg=self.COLOR_OF_CALENDAR_ARROWS)
        self.wid.append(right)
        right.grid(row=0, column=5)

        days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
        for num, name in enumerate(days):
            t = tk.Label(self.parent, text=name[:3],bg=self.COLOR_OF_CALENDAR_LABEL)
            self.wid.append(t)
            t.grid(row=1, column=num)
        #Read Appointments
        appointments=[]
        bookedDays=[]
        with open("appointments.txt", 'r') as appFile:
            reader = csv.reader(appFile)
            for row in reader:
                # removes empty list from loop
                if len(row) > 0:
                    #Check for appointments made by this user
                    if row[0] in self.values:
                        print("yep")
                        #Parse the date into day,month,year
                        dayInt,monthInt,yearInt = row[1].split("/")
                        appointments.append([dayInt,monthInt,yearInt])

        for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
            #If appointment on
            for dayInt,monthInt,yearInt in appointments:
                #Appointment this week
                appWeek = False
                if (int(dayInt) in week) and int(monthInt)==m and int(yearInt) ==y:
                    appWeek=True
                    bookedDays.append(int(dayInt))
                    print(bookedDays)
                    for d, day in enumerate(week):
                        if day in bookedDays:
                            b = tk.Button(self.parent, width=1, bg="red", text=day,
                                          command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                            self.wid.append(b)
                            b.grid(row=w, column=d)
                        else :
                            # print(calendar.day_name[day])
                            b = tk.Button(self.parent, width=1,bg=self.COLOR_OF_DAY_BUTTONS, text=day,
                                            command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                            self.wid.append(b)
                            b.grid(row=w, column=d)
                """
                elif appWeek == True:
                    #Avoid unnecessary re changing of buttons
                    pass
                else:
                    #No appointment this week
                    for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
                        for d, day in enumerate(week):
                            if day:
                                # print(calendar.day_name[day])
                                b = tk.Button(self.parent, width=1, bg=self.COLOR_OF_DAY_BUTTONS, text=day,
                                      command=lambda day=day: self.selection(day, calendar.day_name[(day) % 7]))
                                self.wid.append(b)
                                b.grid(row=w, column=d)
            # Reset bookedDays in order to allow for multiple appointments on the same day
            bookedDays=[]
            """


        sel = tk.Label(self.parent, height=2,bg=self.COLOR_OF_CALENDAR_LABEL, text='{} {} {} {}'.format(
            self.day_name, calendar.month_name[self.month_selected], self.day_selected, self.year_selected))
        self.wid.append(sel)
        sel.grid(row=8, column=0, columnspan=7)

    # Quit out of the calendar and terminate tkinter instance.
    def kill_and_save(self):
        self.parent.destroy()

1 Ответ

1 голос
/ 24 марта 2020

Если то, что я понимаю, правильно, appointments - это список кортежей:

[(11, 3, 2020), (20, 3, 2020), (21, 3, 2020)]

Поэтому я предлагаю проверить, входит ли каждый календарный день в встречи, как показано ниже:

import tkinter as tk
import calendar

class CalendarApp(tk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        self.cal = calendar.Calendar(calendar.SUNDAY)
        self.COLOR_OF_DAY_BUTTONS = '#abcdef'
        self.show_calendar(2020, 3)

    def selection(self, day, day_name):
        pass

    def show_calendar(self, y, m):
        appointments = [
            (11, 3, 2020),
            (20, 3, 2020),
            (21, 3, 2020),
        ]
        for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
            for d, day in enumerate(week):
                if day:
                    # determine the color of current calendar day
                    color = 'red' if (day, m, y) in appointments else self.COLOR_OF_DAY_BUTTONS
                    btn = tk.Button(self.parent, text=day, bg=color,
                                    command=lambda day=day: self.selection(day, calendar.day_name[day%7]))
                    btn.grid(row=w, column=d, sticky='nsew')

root = tk.Tk()
app = CalendarApp(root)
root.mainloop()

Обновлено : изменено решение для работоспособного примера с выводом ниже:

enter image description here

...