QML日历:可见日期列表

时间:2017-08-23 09:47:57

标签: qt calendar qml qt5 qtquickcontrols

有没有办法获取当月视图的可见日期列表(包括上一个/下个月也可见的日期)

2 个答案:

答案 0 :(得分:2)

如果我们检查Calendar here的代码,我们就会发现可疑属性__model。我们发现,它总是count为42 - 这是可见的天数。

问题是,在QML中我们无法真正访问QAbstractItemModel的后代,因为我们需要QModelIndex来获取数据,而不是int而不是{{1}识别角色等 所以我们需要引入一个小助手,它为我们提供roleNames函数,如get(index)所知。作为此基础,我们可以使用我们将通过缺少的公开方法扩展的ListModel

<强> qmlproxymodel.h

QIdentityProxyModel

<强> qmlproxymodel.cpp

#ifndef QMLPROXYMODEL_H
#define QMLPROXYMODEL_H

#include <QObject>
#include <QIdentityProxyModel>
#include <QMap>

class QMLProxyModel : public QIdentityProxyModel
{
    Q_OBJECT
public:
    QMLProxyModel(QObject* parent = nullptr);

public slots:
    QMap<QString, QVariant> get(int row_index) const;
};

#endif // QMLPROXYMODEL_H

然后我们在 main.cpp

中将这个新类型注册到QML
#include "qmlproxymodel.h"

QMLProxyModel::QMLProxyModel(QObject* parent)
    : QIdentityProxyModel(parent)
{

}

QMap<QString, QVariant> QMLProxyModel::get(int row_index) const
{
    QMap<QString, QVariant> ret;
    QModelIndex ind = index(row_index, 0);
    QHash<int, QByteArray> roles = roleNames();

    // for some reason the itemData-method always throw a index-out-of-range exception
    for (int e : roles.keys()) {
        ret.insert(roles.value(e), data(ind, e));
    }

    return ret;
}

最后我们在QML中使用它:

qmlRegisterType<QMLProxyModel>("QMLProxyModel", 1, 0, "QMLProxyModel");

每当模型数据发生变化时 - 即选择下个月时,我输出第一个显示日期的日期。
你应该很容易编写一个JS函数来遍历Calendar { id: cal anchors.fill: parent } QMLProxyModel { id: pm sourceModel: cal.__model onDataChanged: console.log("Some Data has changed", pm.get(0).date) } 的所有(42)个元素,以便将内容添加到你想要的任何数据结构中。

答案 1 :(得分:0)

如果有人有兴趣,我发现了更快的解决方法。以下代码考虑从星期一或星期日开始的一周。

我会检查当月的第一天是哪一天,并获取第一周的星期一/星期日,然后查看day = firstDay + X X goes from 0 to 42的位置。

function checkMonthlyCases(currentYear, currentMonth){
    var firstMonthDay = new Date(currentYear,currentMonth,1,0)
    var firstVisibleDay = new Date(firstMonthDay.getTime() - (((firstMonthDay.getDay() === Locale.Sunday) ? Qt.Sunday : firstMonthDay.getDay()) - 1) * 86400000 )

    if( startDay == Qt.Sunday){
        firstVisibleDay = new Date(firstVisibleDay.getTime() - 86400000);
    }

    for(var i=0; i< 42; i++){ // 42: number of visible days
        var checkDay = new Date(firstVisibleDay.getTime() + i*86400000)
        var count = getDayCaseCount(checkDay)
    }
}