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. Event mark on QCalendarWidget
QtWS25 Last Chance

Event mark on QCalendarWidget

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 2 Posters 1.3k Views
  • 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.
  • rudagR Offline
    rudagR Offline
    rudag
    wrote on last edited by
    #1

    Hi,

    I'd like to place an event mark on a specific QCalendarWidget's cell. This mark could be an image on the top left like in the example:

    https://doc.qt.io/qt-5/qtquickcontrols1-calendar-example.html

    The problem with this example is that I'm find it difficult to adapt Quick Controls / QML to my project. Is there any way to programatically do this?

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Do you mean in QML or QWidget?
      If QWidgts, then like this
      https://wiki.qt.io/How_to_create_a_custom_calender_widget

      You should be able to just call base
      QCalendarWidget::paintCell(painter, rect, date);
      first and then draw an image on top of the default drawing.

      1 Reply Last reply
      2
      • rudagR Offline
        rudagR Offline
        rudag
        wrote on last edited by
        #3

        Hi
        Thanks for the answer.
        I tried this just as a test and it's working fine:

        void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
            {
                if (date.day() == 20) { // test condition
                    // When the conditions are matched, passed QDate is drawn as we like.
                    painter->save();
                    painter->drawRect(rect.x(), rect.y(), 15, 15);
                    painter->fillRect(rect.x(), rect.y(), 15, 15, Qt::red);
                    painter->drawText(rect, Qt::TextSingleLine | Qt::AlignCenter, QString::number(date.day()));
                    painter->restore();
                } else { // if our conditions are not matching, show the default way.
                    QCalendarWidget::paintCell(painter, rect, date);
                }
            }
        

        The problem now is that I can't select the days that match the above condition (day = 20). The cell doesn't get the 'selection' behavior (blue background). Clicked signal is being emitted normally. Did I do something wrong?

        mrjjM 1 Reply Last reply
        0
        • rudagR rudag

          Hi
          Thanks for the answer.
          I tried this just as a test and it's working fine:

          void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
              {
                  if (date.day() == 20) { // test condition
                      // When the conditions are matched, passed QDate is drawn as we like.
                      painter->save();
                      painter->drawRect(rect.x(), rect.y(), 15, 15);
                      painter->fillRect(rect.x(), rect.y(), 15, 15, Qt::red);
                      painter->drawText(rect, Qt::TextSingleLine | Qt::AlignCenter, QString::number(date.day()));
                      painter->restore();
                  } else { // if our conditions are not matching, show the default way.
                      QCalendarWidget::paintCell(painter, rect, date);
                  }
              }
          

          The problem now is that I can't select the days that match the above condition (day = 20). The cell doesn't get the 'selection' behavior (blue background). Clicked signal is being emitted normally. Did I do something wrong?

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @rudag
          Hi
          Nope you didn't do anything wrong
          however the logic in that code
          is that if
          if (date.day() == 20) then we do
          custom drawing
          and else
          we draw normally. (calling base)

          The custom drawing does not handle drawing the selection part as its just a demo.

          However, i was kinda expecting you just to do

          void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
              {
          	    QCalendarWidget::paintCell(painter, rect, date); // draw it normal
                  
          		if ( it has event ) {                     
          			painter->drawPixmap( .... )
          		}     
                  
              }
          

          so you let it draw as normal and then put image on top when it applies.

          rudagR 1 Reply Last reply
          1
          • mrjjM mrjj

            @rudag
            Hi
            Nope you didn't do anything wrong
            however the logic in that code
            is that if
            if (date.day() == 20) then we do
            custom drawing
            and else
            we draw normally. (calling base)

            The custom drawing does not handle drawing the selection part as its just a demo.

            However, i was kinda expecting you just to do

            void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
                {
            	    QCalendarWidget::paintCell(painter, rect, date); // draw it normal
                    
            		if ( it has event ) {                     
            			painter->drawPixmap( .... )
            		}     
                    
                }
            

            so you let it draw as normal and then put image on top when it applies.

            rudagR Offline
            rudagR Offline
            rudag
            wrote on last edited by
            #5

            @mrjj
            Thanks! Its working fine now!

            Just a "bonus" question:

            I'm using

            painter->drawImage(rect.x(), rect.y(), QImage(":/eventindicator.png"));
            

            and it shows the image fine but I get the following every time I click on a date with event:
            libpng warning: iCCP: known incorrect sRGB profile
            Do I have to worry about it?

            mrjjM 1 Reply Last reply
            0
            • rudagR rudag

              @mrjj
              Thanks! Its working fine now!

              Just a "bonus" question:

              I'm using

              painter->drawImage(rect.x(), rect.y(), QImage(":/eventindicator.png"));
              

              and it shows the image fine but I get the following every time I click on a date with event:
              libpng warning: iCCP: known incorrect sRGB profile
              Do I have to worry about it?

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi
              Super.

              • libpng warning: iCCP: known incorrect sRGB profile

              Do I have to worry about it?

              Nope, its just libpng that at some point was changed so it do not like certain
              profiles, mostly from older photoshop.

              https://stackoverflow.com/questions/22745076/libpng-warning-iccp-known-incorrect-srgb-profile

              If you wish, you can strip your image so warning goes away but
              its not harmful in any way as far as i know it.

              rudagR 1 Reply Last reply
              1
              • mrjjM mrjj

                Hi
                Super.

                • libpng warning: iCCP: known incorrect sRGB profile

                Do I have to worry about it?

                Nope, its just libpng that at some point was changed so it do not like certain
                profiles, mostly from older photoshop.

                https://stackoverflow.com/questions/22745076/libpng-warning-iccp-known-incorrect-srgb-profile

                If you wish, you can strip your image so warning goes away but
                its not harmful in any way as far as i know it.

                rudagR Offline
                rudagR Offline
                rudag
                wrote on last edited by
                #7

                @mrjj
                Hello again! I have another question regarding QCalendarWidget. If I should open another thread for this then let me know.

                I need to decrease the week number shown by 1 so it matches my commercial calendar. I didn't find any method like the paintCell() that paints the week number cell. I guess it has something to do with the VerticalHeaderFormat property but I don't know how to use it to achieve what I need. Can you help me?

                Thanks in advance.

                mrjjM 1 Reply Last reply
                0
                • rudagR rudag

                  @mrjj
                  Hello again! I have another question regarding QCalendarWidget. If I should open another thread for this then let me know.

                  I need to decrease the week number shown by 1 so it matches my commercial calendar. I didn't find any method like the paintCell() that paints the week number cell. I guess it has something to do with the VerticalHeaderFormat property but I don't know how to use it to achieve what I need. Can you help me?

                  Thanks in advance.

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi
                  Did you try the example and change the format used ?

                  alt text

                  I dont knwo if that will do it but its a good first try :)

                  rudagR 1 Reply Last reply
                  0
                  • mrjjM mrjj

                    Hi
                    Did you try the example and change the format used ?

                    alt text

                    I dont knwo if that will do it but its a good first try :)

                    rudagR Offline
                    rudagR Offline
                    rudag
                    wrote on last edited by
                    #9

                    @mrjj
                    Hi
                    Unfortunately it doesn't help. The example you mentioned shows only the standard options:

                    verticalHeaderCombo->addItem(tr("ISO week numbers"), QCalendarWidget::ISOWeekNumbers);
                    verticalHeaderCombo->addItem(tr("None"), QCalendarWidget::NoVerticalHeader);
                    

                    I need to decrease the ISOWeekNumbers by 1. Do you know what method draws the week number?

                    mrjjM 1 Reply Last reply
                    0
                    • rudagR rudag

                      @mrjj
                      Hi
                      Unfortunately it doesn't help. The example you mentioned shows only the standard options:

                      verticalHeaderCombo->addItem(tr("ISO week numbers"), QCalendarWidget::ISOWeekNumbers);
                      verticalHeaderCombo->addItem(tr("None"), QCalendarWidget::NoVerticalHeader);
                      

                      I need to decrease the ISOWeekNumbers by 1. Do you know what method draws the week number?

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Hi
                      Ah. sorry. should have checked the docs. I hoped it would have more options. my bad.

                      As far as I know, there is no draw week number function
                      as its drawn by the QTableView and data coms from the model.

                      so I think you will have to subclass the model and overwrite data function to
                      return the wanted value.

                      QVariant QCalendarModel::data(const QModelIndex &index, int role) const
                      {
                          if (role == Qt::TextAlignmentRole)
                              return (int) Qt::AlignCenter;
                          int row = index.row();
                          int column = index.column();
                          if(role == Qt::DisplayRole) {
                              if (m_weekNumbersShown && column == HeaderColumn
                                  && row >= m_firstRow && row < m_firstRow + RowCount) {
                                  QDate date = dateForCell(row, columnForDayOfWeek(Qt::Monday));
                                  if (date.isValid())
                                      return date.weekNumber(); <<<<<<<<<-----------------------
                              }
                      

                      you can live brose the code here
                      https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qcalendarwidget.cpp.html

                      rudagR 1 Reply Last reply
                      0
                      • mrjjM mrjj

                        Hi
                        Ah. sorry. should have checked the docs. I hoped it would have more options. my bad.

                        As far as I know, there is no draw week number function
                        as its drawn by the QTableView and data coms from the model.

                        so I think you will have to subclass the model and overwrite data function to
                        return the wanted value.

                        QVariant QCalendarModel::data(const QModelIndex &index, int role) const
                        {
                            if (role == Qt::TextAlignmentRole)
                                return (int) Qt::AlignCenter;
                            int row = index.row();
                            int column = index.column();
                            if(role == Qt::DisplayRole) {
                                if (m_weekNumbersShown && column == HeaderColumn
                                    && row >= m_firstRow && row < m_firstRow + RowCount) {
                                    QDate date = dateForCell(row, columnForDayOfWeek(Qt::Monday));
                                    if (date.isValid())
                                        return date.weekNumber(); <<<<<<<<<-----------------------
                                }
                        

                        you can live brose the code here
                        https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qcalendarwidget.cpp.html

                        rudagR Offline
                        rudagR Offline
                        rudag
                        wrote on last edited by
                        #11

                        @mrjj
                        Now manipulating the data shown is the easiest part :P
                        Seems like QCalendarModel isn't accessible for subclassing since it doesn't have a header file. Even if I could subclass it I'd have to make my CustomCalendarWidget use it instead of QCalendarModel. I guess there's no way to make it, is there?

                        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