梦想的彼岸花开 2025-01-20 14:22 采纳率: 77.8%
浏览 11
已结题

QCalendarWidget 如何绘制日期底色?

我想实现 QT 的 QCalendarWidget 类的一个派生类,该类可以指定月历中某些月份的某些日期为特定日期,然后将该天的背景色设置为绿色,然后该月中未指定的日期背景色则为红色或其他颜色,我重写了 paintCell 方法。

void MyCalendar::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
{
    QCalendarWidget::paintCell(painter, rect, date);
    QVector<int> vecMonthDays = {1, 3, 7, 8, 12, 21};  // 测试天数

    // 检查当前日期是否在
    if (vecMonthDays.contains(date.day()))
    {
        painter->save();
        painter->fillRect(rect, Qt::green);
        painter->restore();
    }
    else 
    {
        painter->save();
        painter->fillRect(rect, Qt::red);
        painter->restore();
    }
}

用上面的方法颜色是有了,但是日期被覆盖了,这个不是设置背景色,这个是直接填充矩形,要想只设置一下背景色这个该怎么修改?

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2025-01-20 14:25
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    要实现仅设置背景色而不覆盖日期文本的效果,你需要在绘制日期文本之前和之后分别保存和恢复 QPainter 的状态,并且使用透明度来绘制背景色。这样,日期文本仍然可以显示在背景色之上。

    以下是修改后的 paintCell 方法:

    void MyCalendar::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
    {
        QCalendarWidget::paintCell(painter, rect, date);
    
        QVector<int> vecMonthDays = {1, 3, 7, 8, 12, 21};  // 测试天数
    
        // 检查当前日期是否在
        if (vecMonthDays.contains(date.day()))
        {
            painter->save();
            painter->setOpacity(0.5);  // 设置透明度
            painter->fillRect(rect, Qt::green);
            painter->restore();
        }
        else 
        {
            painter->save();
            painter->setOpacity(0.5);  // 设置透明度
            painter->fillRect(rect, Qt::red);
            painter->restore();
        }
    }
    

    详细步骤

    1. 保存和恢复 QPainter 状态

      • 使用 painter->save();painter->restore(); 来确保每次绘制后 QPainter 的状态被正确恢复。
    2. 设置透明度

      • 使用 painter->setOpacity(0.5); 来设置透明度。这可以使背景色半透明,从而不会完全覆盖日期文本。
    3. 填充背景色

      • 使用 painter->fillRect(rect, Qt::green);painter->fillRect(rect, Qt::red); 来填充背景色。

    完整示例代码

    #include <QCalendarWidget>
    #include <QPainter>
    #include <QVector>
    
    class MyCalendar : public QCalendarWidget
    {
    public:
        MyCalendar(QWidget *parent = nullptr) : QCalendarWidget(parent) {}
    
    protected:
        void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const override
        {
            QCalendarWidget::paintCell(painter, rect, date);
    
            QVector<int> vecMonthDays = {1, 3, 7, 8, 12, 21};  // 测试天数
    
            // 检查当前日期是否在
            if (vecMonthDays.contains(date.day()))
            {
                painter->save();
                painter->setOpacity(0.5);  // 设置透明度
                painter->fillRect(rect, Qt::green);
                painter->restore();
            }
            else 
            {
                painter->save();
                painter->setOpacity(0.5);  // 设置透明度
                painter->fillRect(rect, Qt::red);
                painter->restore();
            }
        }
    };
    

    解释

    • 透明度设置:通过 painter->setOpacity(0.5); 设置透明度,使得背景色不会完全覆盖日期文本,同时保持一定的视觉效果。
    • 填充矩形:使用 painter->fillRect(rect, Qt::green);painter->fillRect(rect, Qt::red); 来填充背景色。
    • 保存和恢复状态:通过 painter->save();painter->restore(); 确保每次绘制后 QPainter 的状态被正确恢复。

    这样,你可以实现既设置背景色又保留日期文本的效果。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 1月28日
  • 已采纳回答 1月20日
  • 创建了问题 1月20日