I created a GUI to show some running workouts via PyQt QCalendarWidget. The following code was based on these posts:
I created a subclass in order to overwrite the paint method. This works fine when I have a date hardcoded within the paintCell method. But ideally I would like to run a function first which will return a set of dates/running distances as a dataframe. This dataframe would be then used to "populate" the QCalendarWidget (by adding the running distance as text for the corresponding date for instance).
class MyQtApp(trigui.Ui_MainWindow, QtWidgets.QMainWindow):
def __init__(self):
super(MyQtApp, self).__init__()
self.setupUi(self)
self.Calendar()
self.df = pd.DataFrame()
self.qPlan_Create_btn.clicked.connect(self.draw_running_plan)
def Calendar(self):
self.cal = CalendarWidget(self.qPlan_Widget)
self.cal.resize(1700, 800)
def draw_running_plan(self):
self.df = pd.DataFrame([[25-05-2021, 10], [27-05-2021, 12]], columns=['Date', 'Distance'])
#########
# how can I pass this dataframe to the paintCell
class CalendarWidget(QtWidgets.QCalendarWidget):
def paintCell(self, painter, rect, date):
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
if date == QtCore.QDate(2021, 5, 15):
painter.save()
painter.drawRect(rect)
painter.setPen(QtGui.QColor(168, 34, 3))
painter.drawText(rect, QtCore.Qt.AlignHCenter, 'Hello\nWorld')
painter.drawText(QtCore.QRectF(rect),
QtCore.Qt.TextSingleLine|QtCore.Qt.AlignCenter, str(date.day()))
painter.restore()
else:
QtWidgets.QCalendarWidget.paintCell(self, painter, rect, date)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
qt_app = MyQtApp()
qt_app.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Somehow I need to call the method Calendar from my __init__
. I tried to set self.cal = CalendarWidget (self.qPlan_Widget) within my function draw_running_plan but then the Calendar is not displayed. For info, self.qPlan_Widget is a simple Widget/container that I created via QtDesigner and I initialize it to be a CalendarWidget via the Calendar method. So long story short: after initializing the CalendarWidget, how do I update it with the result of an intermediary function?
Edit: my mistake about the tag it is PySide2 not PyQt
A possible solution is to create a property that the
update()
method of the internal QTableView viewport is used in the setter, which will call the paintEvent method, which in its logic invokes thepaintCell()
method:On the other hand for filtering it is better to convert the date string column (at least that seems what the OP provides) to datetime. And then make a filter based on the smallest date of one day and the one of the next day.