Solved Changing a QCalenderWidgets icons.
-
I was searching for a way to change the next month prev month buttons, but apparently it isnt doable by style sheet, which then lead me to read the source of QCalenderWidget to find out how it declares them.
Which lead me to this in the qcalenderwidget.cpp
void QCalendarWidgetPrivate::updateButtonIcons() { Q_Q(QCalendarWidget); prevMonth->setIcon(q->style()->standardIcon(q->isRightToLeft() ? QStyle::SP_ArrowRight : QStyle::SP_ArrowLeft, 0, q)); nextMonth->setIcon(q->style()->standardIcon(q->isRightToLeft() ? QStyle::SP_ArrowLeft : QStyle::SP_ArrowRight, 0, q)); }
But i have no clue how i am supposed to override that from a custom class based on a QCalendarWidget, nor have i ever seen a private widget before. So i am here asking how i would go about overriding that, or if it is even possible to do so
-
@SolaVitae said in Changing a QCalenderWidgets icons.:
how i am supposed to override that from a custom class based on a QCalendarWidget
You can't.
You can probably hack your way around it though.
prevMonth
andnextMonth
are bothQToolButton
s that are children ofQCalendarWidget
.Something like this (untested code below):
class MyCalendarWidget : public QCalendarWidget{ Q_OBJECT Q_DISABLE_COPY(MyCalendarWidget) public: MyCalendarWidget(QWidget* parent=Q_NULLPTR) :QCalendarWidget(parent){ updateButtonIcons(); } protected: virtual bool MyCalendarWidget::event(QEvent *event) Q_DECL_OVERRIDE{ const bool retVal = QCalendarWidget::event(event); if(event->type() == QEvent::LayoutDirectionChange) updateButtonIcons(); return retVal; } private: void updateButtonIcons(){ const auto btns = findChildren<QToolButton*>(QString(),Qt::FindDirectChildrenOnly); Q_ASSERT(btns.size()==2); QPixmap blueIcon(20,20); blueIcon.fill(Qt::blue); for(QToolButton* tbt : btns) tbt->setIcon(QIcon(blueIcon)); } };
P.S.
Probably worth noting, since this depends on an implementation detail ofQCalendarWidgetPrivate
this carries the same problem as using the private API directly. Qt is free to, for example, change thoseQToolButton
intoQPushButton
at any time and without notice -
the Q_ASSERT Fires correctly and closes my program, but it doesn't correctly change the icons into blue boxes, But since you suggested just finding the children directly (For some reason I didn't think of that) I just made some modifications.
The findChildren does not work if it has the FindDirectChildrenOnly option, I'm not sure if that is because the buttons technically aren't direct children of the QCalendar, but children of the QPrivateCalendar, but after removing the find direct children we end up with
But that was enough to show me that it was possible, so from their, I just went with finding them directly instead of by group with
QToolButton *prevMonth = findChild<QToolButton*>("qt_calendar_prevmonth"); QToolButton *nextMonth = findChild<QToolButton*>("qt_calendar_nextmonth"); prevMonth->setIcon(blueIcon); nextMonth->setIcon(blueIcon);
which results in
and thats what i want to be able to change, so thanks for helping me solve this.PS: Any idea why the drop-down arrow on the month selector is overlapping the word by default? I've never changed or tried to change that, and it's like that on all my calendars by default
-
@SolaVitae said in Changing a QCalenderWidgets icons.:
Any idea why the drop-down arrow on the month selector is overlapping the word by default? I've never changed or tried to change that, and it's like that on all my calendars by default
Does it happen even if you do not apply a stylesheet to the calendar?
-
i know that its a outdated topic, but if i can help anyone:
in QT Designer, QCalendarWidget Stylesheet, add this:
#calendar_objectname QWidget#qt_calendar_prevmonth { qproperty-icon:url ("path/icon.png"); } #calendar_objectname QWidget#qt_calendar_nextmonth { qproperty-icon:url ("path/icon.png"); } hope it will help somebody.
-
@Lemat Thanks, this helped me. I could not find "qproperty-icon" anywhere.
-
@dominicdeo you are welcome
-
this is what worked for me
class CalendarWidget(QtWidgets.QCalendarWidget): def __init__(self, parent=None): super(CalendarWidget, self).__init__(parent, verticalHeaderFormat=QtWidgets.QCalendarWidget.NoVerticalHeader, gridVisible=False) self.setObjectName("patient_visit_date_calendar_widget") prev_button = self.findChild(QtWidgets.QToolButton, "qt_calendar_prevmonth") next_button = self.findChild(QtWidgets.QToolButton, "qt_calendar_nextmonth") # Create QIcon instances for your icons prev_icon = QIcon(":resources/icons/arrow_back.svg") next_icon = QIcon(":resources/icons/arrow_forward.svg") # Set the icons to the buttons prev_button.setIcon(prev_icon) next_button.setIcon(next_icon) for btn in (prev_button, next_button): btn.setIconSize(QtCore.QSize(15, 15)) for d in (QtCore.Qt.Saturday, QtCore.Qt.Sunday,): fmt = self.weekdayTextFormat(d) fmt.setForeground(QtCore.Qt.darkGray) self.setWeekdayTextFormat(d, fmt) self.setStyleSheet(QSS) def paintCell(self, painter, rect, date): if date == self.selectedDate(): painter.save() painter.fillRect(rect, QtGui.QColor("white")) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(QtGui.QColor(10, 186, 181, 100)) r = QtCore.QRect(QtCore.QPoint(), min(rect.width(), rect.height())*QtCore.QSize(1, 1)) r.moveCenter(rect.center()) painter.drawEllipse(r) painter.setPen(QtGui.QPen(QtGui.QColor("white"))) painter.drawText(rect, QtCore.Qt.AlignCenter, str(date.day())) painter.restore() else: super(CalendarWidget, self).paintCell(painter, rect, date)