【Qt学习】借助示例代码实现简易日历项目(三)为todolist新增年、月、周视图

前言

书接上文,这篇文章来谈谈如何在现有的todolist应用中添加日历视图,且除了最常见的月视图外,还包括年视图和周视图。

视图显示

月视图实现

在todolist源码的NewTask界面中,点击选择日期的图标会弹出一个日历视图,其中可以自由选择月份和年份:

可将这一段代码最后的Cancel和OK去掉,并作为月视图放在HomePage中(我将其另存为HomeCalendarView):

qml 复制代码
//HomePageForm.ui.qml中追加如下代码:
    HomeCalendarView {
        id: homeCalendarView
        width: 260
        height: 248
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.rightMargin: 16
        anchors.leftMargin: 16
    }

年视图实现

  • 基本思路:将某一年中的12个月的月视图在界面上依次列出,就组成了该年的年视图。
  • 具体实现:

月视图的关键在于MonthGrid,这是Qt Quick内置的一个日历组件,调用它就会显示某年某月的视图,无需手动计算日历构成

使用前需要先import:

arduino 复制代码
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

下述代码以2023年为例,且由于篇幅所限,仅展示一月的,读者有需要的可以自行复制粘贴多次或者用循环遍历,修改id值及对应属性和显示的文本。

qml 复制代码
    GridLayout {
        id: grid
        columns: 2
        Rectangle{
            width: 150
            height: 150
            border.color:"black"
            border.width: 1
            Text {
                id: jan
                text: qsTr("January")
                anchors.margins: 2
            }
            MonthGrid {
            id: monthGrid1
            month: Calendar.January
            year: 2023
            locale: Qt.locale("zh_CN")
            anchors.top: jan.bottom
            delegate: Text {
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
                //opacity: model.month === monthGrid.month ? 1 : 0
                text: monthGrid1.locale.toString(model.date, "d")
                font: monthGrid1.font
            }
        }
        }
        //此处省略剩余11个月的代码
        ...
        }

最终显示效果如下:

周视图实现

  • 基本思路 我查看了手机内置的日历应用,发现其周视图就是列出周一至周日,当前是周几就在对应的天数那里打点。依据这个实现,我弄了一个简化版的周视图:

这是通过Text的形式展示的。

  • 具体实现 首先需要有周数栏,这可以直接用Qt Quick内置的DayOfWeekRow
qml 复制代码
            DayOfWeekRow {
                id:week_row
                Layout.fillWidth: true
                delegate: Label {
                    required property string narrowName
                    color: Constants.secondaryColor
                    text: narrowName
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                }
            }

其次,在下面有一个文本框:

qml 复制代码
            Text {
                id:week_text
            }

两者被放入Rectangle下的ColumnLayout布局中。

当相关组件加载完成时,获取当前时间,并获取其中的星期天数信息:

qml 复制代码
    Component.onCompleted:{
        var tmp=new Date().toLocaleString(Qt.locale("zh_CN"),Locale.LongFormat)
        var str=tmp.substring(11,14)
        week_text.text="今天是:" + str
    }

视图获取

基础知识

在成功定义了年视图和周视图后,还需要考虑应该如何让用户在需要它时获取到它(而不是将它一股脑塞在首页)。这就涉及到了页面切换的操作。

在Qt中,页面切换有两种基本思路:

  • StackView

通俗理解:StackView就是每进入一个页面,就将当前页面压入栈中,按返回时,就将当前页面pop出来。源码中从主页a跳转到设置页b,设置页中又设置若干个子选项以供跳转采用的就是这种方式。

  • Loader

通俗理解:Loader,顾名思义,加载组件。其基本思路就是比如定义了好几个组件abc,需要显示a的时候就加载a,bc隐藏,需要显示b、c的时候同理。类似于前端某个页面中局部视图切换时的显示-隐藏思路。

具体实现

  • 在Settings.qml中,定义两个点击按钮并编写如下槽:
qml 复制代码
    selectWeekView.onClicked:{
        stackView.push("WeekView.qml")
    }

    selectYearView.onClicked:{
        stackView.push("YearView.qml")
    }

其中,stackView是在源码的App.qml中定义好的:

qml 复制代码
    StackView {
        id: stackView

        anchors.fill: parent
        initialItem: HomePage {
            builtInStyles: root.builtInStyles
        }
    }
  • 将WeekView.qml和YearView.qml都改为Page形式,并添加以下Header:
qml 复制代码
    header: NavBar {
        id: header
        visible: true
        //YearView.qml为"YearView"
        titleText:"WeekView"
        previousPageTitle: qsTr("Settings")
        backButton.onClicked: {
            stackView.pop()
        }
    }

至此,相关视图的显示和获取均已完成。

相关推荐
码农新猿类17 分钟前
初入OpenCV
qt·opencv·计算机视觉
洛克希德马丁2 小时前
QLineEdit增加点击回显功能
c++·qt·ui
向日葵xyz3 小时前
Qt5与现代OpenGL学习(十一)OpenGL Widget鼠标控制直线旋转
开发语言·qt·学习
小宋加油啊5 小时前
Mac QT水平布局和垂直布局
开发语言·qt·macos
伐尘17 小时前
【Qt】编译 Qt 5.15.x For Windows 基础教程 Visual Studio 2019 MSVC142 x64
windows·qt·visual studio
吃面不喝汤6617 小时前
破解 Qt QProcess 在 Release 模式下的“卡死”之谜
开发语言·qt
charlie1145141911 天前
逐步理解Qt信号与槽机制
数据库·qt
yaso_zhang1 天前
当生产了~/qt-arm/bin/qmake,可以单独编译其他-源码的某个模块,如下,编译/qtmultimedia
qt
code bean1 天前
【Qt/C++】深入理解 Lambda 表达式与 `mutable` 关键字的使用
开发语言·c++·qt
爱看书的小沐2 天前
【小沐学GIS】基于C++绘制二维瓦片地图2D Map(QT、OpenGL、GIS)
c++·qt·gis·opengl·glfw·glut·二维地图