zoukankan      html  css  js  c++  java
  • Qt开源作品30-农历控件

    一、前言

    农历控件在国产linux中必备的控件之一,毕竟要适应国人的习惯,你看win10系统的日历,现在点开来直接就有农历在上面,非常方便人性化,所以在很多用Qt做的项目中,也有农历控件的应用场景,而Qt自带的日历控件比较简单,仔细看过源码的人也只知道,其实就是一堆微调框,下拉框,表格组成的,于是打算借用此方法造一个农历控件,本控件的算法是倪大侠提供的,个人测试下来还是没有问题的,造这个农历控件最大的难点是如何根据日期计算农历时间,再加上一些农历的节气之类的,这个网上估计也有很多的算法参考。

    主要功能:

    1. 可设置边框颜色/周末颜色/角标颜色/农历节日颜色
    2. 可设置当前月文字颜色/其他月文字颜色/选中日期文字颜色/悬停日期文字颜色
    3. 可设置当前月农历文字颜色/其他月农历文字颜色/选中日期农历文字颜色/悬停日期农历文字颜色
    4. 可设置当前月背景颜色/其他月背景颜色/选中日期背景颜色/悬停日期背景颜色
    5. 可设置三种选中背景模式,矩形背景+圆形背景+图片背景
    6. 可直接切换到上一年/下一年/上一月/下一月/转到今天
    7. 可设置是否显示农历信息,不显示则当做正常的日历使用
    8. 支持1900年-2099年范围
    9. 很方便改成多选日期

    二、代码思路

    void LunarCalendarItem::paintEvent(QPaintEvent *)
    {
        //绘制准备工作,启用反锯齿
        QPainter painter(this);
        painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    
        //绘制背景和边框
        drawBg(&painter);
    
        //优先绘制选中状态,其次绘制悬停状态
        if (select) {
            drawBgCurrent(&painter, selectBgColor);
        } else if (hover) {
            drawBgCurrent(&painter, hoverBgColor);
        }
    
        //绘制日期
        drawDay(&painter);
    
        //绘制农历信息
        drawLunar(&painter);
    }
    
    void LunarCalendarItem::drawBg(QPainter *painter)
    {
        painter->save();
    
        //根据当前类型选择对应的颜色
        QColor bgColor = currentBgColor;
        if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
            bgColor = otherBgColor;
        }
    
        painter->setPen(borderColor);
        painter->setBrush(bgColor);
        painter->drawRect(rect());
    
        painter->restore();
    }
    
    void LunarCalendarItem::drawBgCurrent(QPainter *painter, const QColor &color)
    {
        int width = this->width();
        int height = this->height();
        int side = qMin(width, height);
    
        painter->save();
    
        painter->setPen(Qt::NoPen);
        painter->setBrush(color);
    
        //根据设定绘制背景样式
        if (selectType == SelectType_Rect) {
            painter->drawRect(rect());
        } else if (selectType == SelectType_Circle) {
            int radius = side / 2 - 3;
            painter->drawEllipse(QPointF(width / 2, height / 2), radius, radius);
        } else if (selectType == SelectType_Triangle) {
            int radius = side / 3;
            QPolygon pts;
            pts.setPoints(3, 1, 1, radius, 1, 1, radius);
            painter->drawRect(rect());
            painter->setBrush(superColor);
            painter->drawConvexPolygon(pts);
        } else if (selectType == SelectType_Image) {
            //等比例缩放居中绘制
            QImage img(bgImage);
            if (!img.isNull()) {
                img = img.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
                int x = (width - img.width()) / 2;
                int y = (height - img.height()) / 2;
                painter->drawImage(x, y, img);
            }
        }
    
        painter->restore();
    }
    
    void LunarCalendarItem::drawDay(QPainter *painter)
    {
        int width = this->width();
        int height = this->height();
        int side = qMin(width, height);
    
        painter->save();
    
        //根据当前类型选择对应的颜色
        QColor color = currentTextColor;
        if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
            color = otherTextColor;
        } else if (dayType == DayType_WeekEnd) {
            color = weekColor;
        }
    
        if (select) {
            color = selectTextColor;
        } else if (hover) {
            color = hoverTextColor;
        }
    
        painter->setPen(color);
    
        if (showLunar) {
            QFont font;
            font.setPixelSize(side / 2.7);
            painter->setFont(font);
    
            QRect dayRect = QRect(0, 0, width, height / 1.7);
            painter->drawText(dayRect, Qt::AlignHCenter | Qt::AlignBottom, QString::number(date.day()));
        } else {
            QFont font;
            font.setPixelSize(side / 2);
            painter->setFont(font);
    
            QRect dayRect = QRect(0, 0, width, height);
            painter->drawText(dayRect, Qt::AlignCenter, QString::number(date.day()));
        }
    
        painter->restore();
    }
    
    void LunarCalendarItem::drawLunar(QPainter *painter)
    {
        if (!showLunar) {
            return;
        }
    
        int width = this->width();
        int height = this->height();
        int side = qMin(width, height);
    
        painter->save();
    
        //判断当前农历文字是否节日,是节日且是当月则用农历节日颜色显示
        bool exist = (!listDayName.contains(lunar) && dayType != DayType_MonthPre && dayType != DayType_MonthNext);
    
        //根据当前类型选择对应的颜色
        QColor color = currentLunarColor;
        if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
            color = otherLunarColor;
        }
    
        if (select) {
            color = selectTextColor;
        } else if (hover) {
            color = hoverTextColor;
        } else if (exist) {
            color = lunarColor;
        }
    
        painter->setPen(color);
    
        QFont font;
        font.setPixelSize(side / 5);
        painter->setFont(font);    
    
        QRect lunarRect(0, height / 2, width, height / 2);
        painter->drawText(lunarRect, Qt::AlignCenter, lunar);
    
        painter->restore();
    }
    

    三、效果图

    四、开源主页

    以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。

    1. 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
    2. 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
    3. 个人主页:https://blog.csdn.net/feiyangqingyun
    4. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
  • 相关阅读:
    基于协同过滤的个性化Web推荐
    自动推荐系统效果为什么不好
    基于模糊聚类和协同过滤的混合推荐系统
    海量数据处理之蓄水池抽样算法
    心灵启发--不羡慕别人的生活
    ubuntu安装软件整理
    Hadoop系列
    网页返回错误编号含义整理
    找出单链表的中间位置指针
    【python爬虫】根据查询词爬取网站返回结果
  • 原文地址:https://www.cnblogs.com/feiyangqingyun/p/13063743.html
Copyright © 2011-2022 走看看