gpt4 book ai didi

python - 将项目添加到 QCalendarWidget 中的 QTableView

转载 作者:行者123 更新时间:2023-12-01 07:09:06 26 4
gpt4 key购买 nike

我目前正在制作一个带有日历的待办事项应用程序。每当用户在特定日期发生事件时,左上角就会出现一个红色圆圈。每当用户双击日期时,我希望它显示一个新窗口,其中包含当天事件的信息。但是,我无法将信息存储到每个日期中。我怎样才能让每个日期都有一个可以存储事件的列表?

这是用户界面:

enter image description here

下面是子类 QCalendarWidget 的代码:

class TodoCalendar(QtWidgets.QCalendarWidget):
def __init__(self, list_of_events, *args, **kwargs):
super().__init__(*args, **kwargs)
self.list_of_events = list_of_events
//list_of_events is a list of all events the user has created

self.table = self.findChild(QtWidgets.QTableView)
self.table.viewport().installEventFilter(self)

def paintCell(self, painter, rect, date):
super().paintCell(painter, rect, date)
for event in self.list_of_events.values():
if event.due_time == date:
painter.setBrush(Qt.red)
painter.drawEllipse(rect.topLeft() + QPoint(12, 7), 3, 3)

def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseButtonDblClick and source is self.table.viewport()):
index = self.table.indexAt(event.pos())
print(f"row: {index.row()}, column: {index.column()}, text: {index.data()}")
return super().eventFilter(source, event)

这里还有 list_of_events 的列表:

{'test changed': <CustomWidgets.TodoEvent object at 0x00000230A5A72908>, 'due 10/8': <CustomWidgets.TodoEvent object at 0x00000230A5AA5080>, 'also due 10/9': <CustomWidgets.TodoEvent object at 0x00000230A5AC4B00>, 'also due 10/9 too': <CustomWidgets.TodoEvent object at 0x00000230A5AD0550>, 'due 10/9 too too': <CustomWidgets.TodoEvent object at 0x00000230A5AD0A90>, '10/9 2': <CustomWidgets.TodoEvent object at 0x00000230A5AD6438>, '10/10': <CustomWidgets.TodoEvent object at 0x00000230A5AD64A8>, '10/10 also': <CustomWidgets.TodoEvent object at 0x00000230A5AD64E0>, '10/10 2': <CustomWidgets.TodoEvent object at 0x00000230A5AD6550>, '10/10 3': <CustomWidgets.TodoEvent object at 0x00000230A5AD65C0>, '10/10 4': <CustomWidgets.TodoEvent object at 0x00000230A5AD6630>, 'due 10/9 changed': <CustomWidgets.TodoEvent object at 0x00000230A5AD6668>}

每个 toDoEvent 都有标题、due_time、remind_time 和说明

最佳答案

不是按日期存储在某些事件中,另一种方法是获取给定行和列的日期,然后过滤事件。

问题是没有公共(public)方法来计算给定行和列的日期,因此我的解决方案使用 Qt private API code .

考虑到上述情况,解决方案是:

import random
from dataclasses import dataclass

from PyQt5 import QtCore, QtGui, QtWidgets


@dataclass
class Todo:
date: QtCore.QDate
name: str


class TodoCalendar(QtWidgets.QCalendarWidget):
def __init__(self, list_of_events, *args, **kwargs):
super().__init__(*args, **kwargs)
self.list_of_events = list_of_events

self.table = self.findChild(QtWidgets.QTableView)
self.table.viewport().installEventFilter(self)

def paintCell(self, painter, rect, date):
super().paintCell(painter, rect, date)
for event in self.list_of_events:
if event.date == date:
painter.setBrush(QtCore.Qt.red)
painter.drawEllipse(rect.topLeft() + QtCore.QPoint(12, 7), 3, 3)

def eventFilter(self, source, event):
if (
event.type() == QtCore.QEvent.MouseButtonDblClick
and source is self.table.viewport()
):
index = self.table.indexAt(event.pos())
date = self.dateForCell(index.row(), index.column())
today_events = [ev for ev in self.list_of_events if ev.date == date]
if today_events:
print(today_events)
return super().eventFilter(source, event)

def referenceDate(self):
refDay = 1
while refDay <= 31:
refDate = QtCore.QDate(self.yearShown(), self.monthShown(), refDay)
if refDate.isValid():
return refDate
refDay += 1
return QtCore.QDate()

@property
def firstColumn(self):
return (
1
if self.verticalHeaderFormat() == QtWidgets.QCalendarWidget.ISOWeekNumbers
else 0
)

@property
def firstRow(self):
return (
0
if self.horizontalHeaderFormat()
== QtWidgets.QCalendarWidget.NoHorizontalHeader
else 1
)

def columnForDayOfWeek(self, day):
if day < 1 or day > 7:
return -1
column = day - self.firstDayOfWeek()
if column < 0:
column += 7
return column + self.firstColumn

def columnForFirstOfMonth(self, date):
return (self.columnForDayOfWeek(date.dayOfWeek()) - (date.day() % 7) + 8) % 7

def dateForCell(self, row, column):
if (
row < self.firstRow
or row > (self.firstRow + 6 - 1)
or column < self.firstColumn
or column > (self.firstColumn + 7 - 1)
):
return QtCore.QDate()
refDate = self.referenceDate()
if not refDate.isValid():
return QtCore.QDate()
columnForFirstOfShownMonth = self.columnForFirstOfMonth(refDate)
if columnForFirstOfShownMonth - self.firstColumn < 1:
row -= 1
requestedDay = (
7 * (row - self.firstRow)
+ column
- columnForFirstOfShownMonth
- refDate.day()
+ 1
)
return refDate.addDays(requestedDay)


if __name__ == "__main__":
import sys

app = QtWidgets.QApplication(sys.argv)

events = [
Todo(QtCore.QDate.currentDate().addDays(random.randint(1, 10)), f"name-{i}")
for i in range(15)
]

w = TodoCalendar(events)
w.show()
sys.exit(app.exec_())

关于python - 将项目添加到 QCalendarWidget 中的 QTableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58313818/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com