КОНТЕКСТ
Я пытаюсь создать собственный календарь (виджет Tkinter), который имеет следующие атрибуты / функции:
- Каждый столбец представляет 1 день
- Каждая строка будет представлять человека
- Она имеет бесконечную горизонтальную прокрутку -> такон может бесконечно идти в прошлое и настоящее
- ячейки (прямоугольники) в календаре будут интерактивными, так что если я нажму левую кнопку мыши, я могу выбрать определенные ячейки для дальнейшей работы / функции
Это будет выглядеть примерно так:
(Примечание к изображению: красный столбец слева будет отдельным виджетом рамки. Я только что включил его в эскиз, чтобы показать назначение строк в календаре)
МОЙ ПЛАН
Чтобы иметь возможность взаимодействовать с клетками после построения календаря, я планируюch виджет объекта хранится в массиве с именем self.cells
.
Также, поскольку я хочу, чтобы он бесконечно уходил в прошлое и будущее, при инициализации полоса прокрутки календаря будет посередине.
МОЙ ПРОГРЕСС (КОД)
import tkinter as tk
import datetime
CELL_SIZE = (100, 50)
FIRST_ROW_HEIGHT = 20
class Cell(tk.Canvas):
def __init__(self, root,
width = CELL_SIZE[0],
height = CELL_SIZE[1],
highlightthickness = 1,
background = 'white',
highlightbackground = 'black',
highlightcolor = 'red',
*args, **kwargs):
tk.Canvas.__init__(self, root,
width = width,
height = height,
background = background,
highlightthickness = highlightthickness,
highlightbackground = highlightbackground,
highlightcolor = highlightcolor,
*args, **kwargs)
class Calendar(tk.Frame):
def __init__(self, root, rows=0, *args, **kwargs):
tk.Frame.__init__(self, root, *args, **kwargs)
# create the canvas and frame
self.calendar_canvas = tk.Canvas(self)
self.calendar_frame = tk.Frame(self.calendar_canvas)
self.calendar_canvas.create_window((4,4), window=self.calendar_frame, anchor="nw", tags="self.calendar_frame")
self.calendar_canvas.pack(side="top", fill="both", expand=True)
# building scrollbar
self.scrollbar = tk.Scrollbar(self, orient='horizontal', command=self.calendar_canvas.xview)
self.scrollbar.pack(side="bottom", fill="x")
# hooking up scrollbar
self.calendar_canvas.configure(xscrollcommand=self.scrollbar.set)
self.calendar_frame.bind("<Configure>", self.onFrameConfigure)
# variables
self.rows = rows
self.cells = []
def onFrameConfigure(self, event):
self.calendar_canvas.configure(scrollregion=self.calendar_canvas.bbox("all"))
def set(self, day=0):
today = datetime.date.today()
for i in range(day):
self.cells.append([])
# create first row (indicating the date)
cell = Cell(self.calendar_frame, height=FIRST_ROW_HEIGHT)
cell.grid(row=0, column=i)
# add the date label into the first row
cell.create_text(
CELL_SIZE[0]/2,
FIRST_ROW_HEIGHT/2,
text = (today + datetime.timedelta(days=i)).strftime('%d/%m/%y'))
for c in range(self.rows):
cell = Cell(self.calendar_frame)
cell.grid(row=c+1, column=i)
self.cells[i].append(cell)
Calendar
- мой виджет пользовательского календаря в разработке.Мне удается подключить эту структуру, похожую на электронную таблицу, с помощью полосы прокрутки благодаря этому ответу (из @ Ethan Field ), который также послужил моей отправной точкой (базовый код).
В настоящее время виджет Calendar
способен создавать n количество дней (начиная с сегодняшнего дня) с помощью функции Calendar.set()
.
Вы можете попробовать виджет, используя этот код:
root = tk.Tk()
calendar = Calendar(root, rows=3)
calendar.set(day=10)
calendar.pack(fill='both', expand=True)
root.mainloop()
ВОПРОС / ВОПРОС
Как реализовать эффект бесконечная прокрутка ?Я понятия не имею, как заставить его работать.
Разные заметки
- Python 3, 64-битный
- Windows 7, 64-битный
РЕДАКТИРОВАТЬ # 1 - создано addFuture()
функция
# under class Calendar:
def addFuture(self, day=0):
today = datetime.date.today()
for i in range(day):
index = i + self.lastColumn
self.cells.append([])
# create first row (indicating the date)
cell = Cell(self.calendar_frame, height=FIRST_ROW_HEIGHT)
cell.grid(row=0, column=index)
# add the date label into the first row
cell.create_text(
CELL_SIZE[0]/2,
FIRST_ROW_HEIGHT/2,
text = (today + datetime.timedelta(days=index)).strftime('[%a] %d/%m/%y'))
for c in range(self.rows):
cell = Cell(self.calendar_frame)
cell.grid(row=c+1, column=index)
self.cells[i].append(cell)
self.lastColumn = self.lastColumn + day
Эта addFuture()
функция только слегка изменена set()
функция.addFuture()
можно вызывать несколько раз, и каждый раз он добавляет day
количество дней в календарь.Просто нужно подключить полосу прокрутки вверх.Однако, как мне addPast()
?
РЕДАКТИРОВАТЬ # 2 - бесконечная прокрутка в будущее работает!
Команды onFrameConfigure
вызываются всякий раз, когдапользователь перетаскивает полосу прокрутки, поэтому я добавил оператор if self.scrollbar.get()[1] > 0.9:
, чтобы проверить, приближается ли ось x полосы прокрутки к крайнему правому концу 1109 *.Если это так, он выполняет функцию добавления дополнительных дней, и полоса прокрутки каким-то образом автоматически перенастраивает шкалу (я понятия не имею , почему , но это работает).
def onFrameConfigure(self, event):
self.calendar_canvas.configure(scrollregion=self.calendar_canvas.bbox("all"))
if self.scrollbar.get()[1] > 0.9:
self.addFuture(day=10)
Таким образом, мое окно имеет бесконечную прокрутку в будущее.Теперь у меня вопрос как заставить его бесконечно прокручиваться в прошлое (или слева)? .
Я могу обнаружить полосу прокрутки, когда она приближается к левой стороне, используя этот оператор:if self.scrollbar.get()[1] < 0.1:
.Однако мне нужна какая-то команда self.addPast()
, которая служит той же цели, что и команда self.addFuture()
, но (как следует из названия) добавляет дни слева.