Search code examples
qtqcalendarwidgetqdateedit

How to change color for inactive days in QDateEdit or QCalendarWidget


Help me please, my friends!I need to calendar widget look like this: desired calendar

But i have a problem. I only get this: my calendar

I need to do this: dates that are out of range (minimalDate, maximumDate) should be colored as inactive (main color for active dates is black, then for inactive dates is gray, for example). Sorry for my bad english:)

I'm trying to write like this:

/* activel days */
QCalendarWidget QAbstractItemView:enabled 
{
    font-size:24px;  
    color: rgb(180, 180, 180);  
    background-color: black;  
    selection-background-color: rgb(64, 64, 64); 
    selection-color: rgb(0, 255, 0); 
}
 
/* days inactive */
QCalendarWidget QAbstractItemView:disabled { color: rgb(64, 64, 64); }

Solution

  • You should create your own custom calendar class derived from QCalendarWidget and reimplement void QCalendarWidget::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const method.

    So let's create a Calendar class in the Calendar.h:

    #include <QCalendarWidget>
    
    class Calendar : public QCalendarWidget
    {
    public:
        Calendar(QWidget *parent = nullptr);
        void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const override;
    };
    
    

    Implement this class in Calendar.cpp:

    #include "Calendar.h"
    
    #include <QPainter>
    
    Calendar::Calendar(QWidget *parent)
        : QCalendarWidget(parent)
    {}
    
    void Calendar::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
    {
        // change color for dates before current date
        if (date < QDate::currentDate())
        {
            painter->save();
            // set color for the text
            painter->setPen(QColor(64, 64, 64));
            // draw text with new color
            painter->drawText(rect, Qt::TextSingleLine | Qt::AlignCenter, QString::number(date.day()));
    
            // here you can draw anything you want       
    
            painter->restore();
        } else {
            // draw cell in standard way
            QCalendarWidget::paintCell(painter, rect, date);
        }
    }
    
    

    And after that if you're using Qt Creator, you can add QCalendarWidget from the left bar to your widget, right click on it and open Promote to menu. Add Calendar to Promoted class name and check that Header file is correct. Hit Add to add Calendar to the promoted classes list and finally hit Promote to turn the QCalendarWidget on your form into a Calendar.

    After that I get the following widget (sorry for Russian):

    custom calendar