Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Changing a QCalenderWidgets icons.
Forum Updated to NodeBB v4.3 + New Features

Changing a QCalenderWidgets icons.

Scheduled Pinned Locked Moved Solved General and Desktop
qcalenderwidgetqprivatewidget
8 Posts 5 Posters 3.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SolaVitaeS Offline
    SolaVitaeS Offline
    SolaVitae
    wrote on last edited by
    #1

    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

    VRoninV 1 Reply Last reply
    0
    • SolaVitaeS SolaVitae

      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

      VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      @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 and nextMonth are both QToolButtons that are children of QCalendarWidget.

      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 of QCalendarWidgetPrivate this carries the same problem as using the private API directly. Qt is free to, for example, change those QToolButton into QPushButton at any time and without notice

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      3
      • SolaVitaeS Offline
        SolaVitaeS Offline
        SolaVitae
        wrote on last edited by
        #3

        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 alt text

        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
        alt text
        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

        VRoninV 1 Reply Last reply
        1
        • SolaVitaeS SolaVitae

          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 alt text

          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
          alt text
          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

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          @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?

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          0
          • LematL Offline
            LematL Offline
            Lemat
            wrote on last edited by
            #5

            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.
            

            Time to elevate.

            D 1 Reply Last reply
            3
            • LematL Lemat

              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.
              
              D Offline
              D Offline
              dominicdeo
              wrote on last edited by
              #6

              @Lemat Thanks, this helped me. I could not find "qproperty-icon" anywhere.

              LematL 1 Reply Last reply
              0
              • D dominicdeo

                @Lemat Thanks, this helped me. I could not find "qproperty-icon" anywhere.

                LematL Offline
                LematL Offline
                Lemat
                wrote on last edited by
                #7

                @dominicdeo you are welcome

                Time to elevate.

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  Rukaya
                  wrote on last edited by
                  #8

                  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)
                  
                  
                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved