Calendar in Qt via QML(Solved)



  • Hi guys,
    Actually i was trying to display a calendar pop in QML,but still now i cant be able to work it out...I have brought the QML calendar ,but i don't know how to set the date,if i clicked any date means.It should display the month,day,year of that particular day...and also the time...Below is the code...Please help me..

    /***********************************************************************/
    @import QtQuick 1.0

    Rectangle {
    id: calendar
    width: 400; height: 300
    color: "#303030"
    property date today: new Date()
    property date showDate: new Date()
    property int daysInMonth: new Date(showDate.getFullYear(), showDate.getMonth() + 1, 0).getDate()
    property int firstDay: new Date(showDate.getFullYear(), showDate.getMonth(), 1).getDay()

    Item {
        id:title
        anchors.top: parent.top
        anchors.topMargin: 10
        width: parent.width
        height: childrenRect.height
    
        Image {
            id:monthright
            source: "Images/previous.png"
            anchors.left: parent.left
            anchors.leftMargin: 10
    
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    showDate = new Date(showDate.getFullYear(), showDate.getMonth(), 0)
                }
            }
        }
        Text {
            id:month
            color: "white"
            text: Qt.formatDateTime(showDate, "MMMM")
            font.bold: true
            anchors.left:monthright.right
        }
        Image {
              source: "Images/next.png"
              anchors.left:month.right
              MouseArea {
                  anchors.fill: parent
                  onClicked:
                  {
                      showDate = new Date( showDate.getFullYear(), showDate.getMonth() + 1, 1)
                      console.log(showDate)
                  }
              }
          }
            Image {
          source: "Images/previous.png"
          anchors.right: yearleft.left
          MouseArea {
              anchors.fill: parent
              onClicked: {
                  showDate = new Date(showDate.getFullYear()-1,0)
                  console.log(showDate)
    
              }
          }
      }
      Text {
          id:yearleft
          color: "white"
          text: Qt.formatDateTime(showDate, "yyyy")
          font.bold: true
          anchors.right:year.left
      }
    
      Image {
            id:year
            source: "Images/next.png"
            anchors.right: parent.right
            anchors.rightMargin: 10
    
            MouseArea {
                anchors.fill: parent
                onClicked:
                {
                    showDate = new Date(showDate.getFullYear()+1, 1)
                    boxtext.text=new Date
                    console.log(showDate)
                    }
            }
        }
    }
    
    function isToday(index) {
        if (today.getFullYear() != showDate.getFullYear())
            return false;
        if (today.getMonth() != showDate.getMonth())
            return false;
    
        return (index === today.getDate() - 1)
    }
    
    Item {
        id: dateLabels
        anchors.top: title.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 10
    
        height: calendar.height - title.height - 20 - title.anchors.topMargin
        property int rows: 6
        Item {
            id: dayLabels
            width: parent.width
            height: childrenRect.height
    
            Grid {
                columns: 7
                spacing: 10
    
                Repeater {
                    model: 7
    
                    Rectangle {
                        color: "#00ffffff"
                        width: (calendar.width - 20 - 60)/7
                        height: childrenRect.height
    
                        Text {
                            color: "#00000C"
                            // Qt dates (for formatting) and JavaScript dates use different ranges
                            // (1-7 and 0-6 respectively), so we add 1 to the day number.
                            text: Qt.formatDate(new Date(showDate.getFullYear(), showDate.getMonth(), index - firstDay +1), "ddd");
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                    }
                }
            }
        }
        Item {
            id: dateGrid
            width: parent.width
            anchors.top: dayLabels.bottom
            anchors.topMargin: 5
            anchors.bottom: parent.bottom
    
            Grid {
                columns: 7
                rows: dateLabels.rows
                spacing: 10
    
                Repeater {
                    model: firstDay + daysInMonth
    
                    Rectangle {
    
                        color: {
                            if (index < firstDay)
                                calendar.color="green";
                            else
                            {
                                if(isToday(index-firstDay))
                                    color="yellow";
                                else
                                    color="#eeeeee"
                            }
                               // isToday(index - firstDay) ? "#ffffdd" : "#eeeeee";
                        }
                        width: (calendar.width - 20 - 60)/7
                        height: (dateGrid.height - (dateLabels.rows - 1)*10)/dateLabels.rows
    
                        Text {
                            anchors.centerIn: parent
                            text: index + 1 - firstDay
                            opacity: (index < firstDay) ? 0 : 1
                            font.bold: isToday(index - firstDay)
                        }
                    }
                }
                 }
        }
        }
    }
    

    @



  • Hi,

    I have difficulties trying to understanding your question.
    What excactly do you want to add to the calander example you posted?

    What do you mean with 'set the date'? changing the date/time of the system, or clicking on a day in the calander and then show something?

    Assuming you mean clicking on a day in the calander, you need to add a MouseArea to it so you can click it, and then do something.
    I tried your example, there is a bug on line 82, so I commented it out.
    I added a MouseArea at line 174 to show the data of that day on the debug console.

    @
    ...
    Item {
    id: dateGrid
    width: parent.width
    anchors.top: dayLabels.bottom
    anchors.topMargin: 5
    anchors.bottom: parent.bottom

    Grid {
    columns: 7
    rows: dateLabels.rows
    spacing: 10

    Repeater {
    model: firstDay + daysInMonth

    Rectangle {

    color: {
     if (index < firstDay)
      calendar.color="green";
     else
     {
      if(isToday(index-firstDay))
       color="yellow";
      else
       color="#eeeeee"
     }
     // isToday(index - firstDay) ? "#ffffdd" : "#eeeeee";
    }
    width: (calendar.width - 20 - 60)/7
    height: (dateGrid.height - (dateLabels.rows - 1)*10)/dateLabels.rows
    
    Text {
     anchors.centerIn: parent
     text: index + 1 - firstDay
     opacity: (index < firstDay) ? 0 : 1
     font.bold: isToday(index - firstDay)
    }
    
    MouseArea {
     anchors.fill: parent
     onClicked: {
      var clickedDate = new Date( showDate.getFullYear(), showDate.getMonth() + 1, index + 1 - firstDay)
      console.log(clickedDate) }
     
    }
    

    }
    }
    }
    }
    ...
    @

    If you mean something else, please clarify your question.



  • Much pleased with your reply..Actually i want to show calendar popup on clicking one button.That calendar should support system calendar..Suppose if i clicked any of the date means,it should show its day,month,year and time...I too worked your mouseclick which you have added,but its not working...Now you understand...Could you please find out the solution..below is the output..And i dont know how to insert my picture which i got as output...



  • Very much thanks ,
    It works.......What i have expected....But need to do some changes...If i click any date means,its color should change...I'm working....If any query means,i will ask u boss.thanks a lot



  • I'm glad 'it works'.

    I do not know if you need any further help, I find it very hard to understand your replies.

    So I'm guessing here, don't know if this is what you're looking for. If you want to change the color when the mouse is pressed and change it back when released the easiest in that case would be to give the mouse area an id and then use the mousearea pressed property to change the rectangle color.
    @
    ...
    Item {
    id: dateGrid
    width: parent.width
    anchors.top: dayLabels.bottom
    anchors.topMargin: 5
    anchors.bottom: parent.bottom

    Grid {
    columns: 7
    rows: dateLabels.rows
    spacing: 10

    Repeater {
    model: firstDay + daysInMonth

    Rectangle {

    property color normalColor
    Component.onCompleted: {
     if (index < firstDay)
      normalColor = calendar.color="green";
    
     else
     {
      if(isToday(index-firstDay))
         normalColor = "yellow";
      else
       normalColor ="#eeeeee"
     }
    }
    color: dateMouse.pressed?"blue":normalColor
    width: (calendar.width - 20 - 60)/7
    height: (dateGrid.height - (dateLabels.rows - 1)*10)/dateLabels.rows
    
    Text {
     anchors.centerIn: parent
     text: index + 1 - firstDay
     opacity: (index < firstDay) ? 0 : 1
     font.bold: isToday(index - firstDay)
    }
    
    MouseArea {
     id: dateMouse
     anchors.fill: parent
     onClicked: {
      var clickedDate = new Date( showDate.getFullYear(), showDate.getMonth() + 1, index + 1 - firstDay)
      console.log(clickedDate)
     }
    }
    

    }
    }
    }
    }
    ...
    @
    On line 20 I added a property to 'remember' the original color.

    I noticed that on line 6 you do color: "#303030" and later you do calendar.color="green", why don't you set the color of the calendar to "green" directly?

    Please let me know if I can do anything else for you.



  • thanks boss..If i put that "green" color in starting itself means...Only for the current month,it will be working..If we pressed next icon means green color will be changed to some other color(defaultly "white"...I guess it so)
    Actually i want to display the date in the format (dd/mm/YYYY)..How to do it...
    Very pleased....



  • You should be able to use
    @
    console.log(Qt.formatDate(clickedDate, "dd/MM/yyyy"))
    @

    to do that.



  • thank you sir for your immediate response.....But another problem arises..If i clicked new date means,it should come to Bold letter(yellow color)..Likewise if i clicked some other date means,now it should become bold letter and previous clicked date should go to normal one.



  • I should say that the code is becoming a little bit ugly. I would use a component with states for each day rectangle, but to illustrate how it can be done here an example.

    I'm happy to help, but I get the feeling you're a bit unexperienced in QML, maybe it is wise to first do some reading "QML intro":http://qt.digia.com/Product/Learning/Education/elearning/online-training/Qt-Essentials---Qt-Quick-Edition/#.UatX1EA5nfI

    @
    Item {
    id: dateGrid
    width: parent.width
    anchors.top: dayLabels.bottom
    anchors.topMargin: 5
    anchors.bottom: parent.bottom
    property int currentActive: -1
    Grid {
    columns: 7
    rows: dateLabels.rows
    spacing: 10

    Repeater {
    id: repeater
    model: firstDay + daysInMonth
    Rectangle {
    property bool highLighted: false
    property color normalColor

    Component.onCompleted: {
     if (index < firstDay)
      normalColor = calendar.color="green";
    
     else
     {
      if(isToday(index-firstDay))
         normalColor = "yellow";
      else
       normalColor ="#eeeeee"
     }
    }
    color: dateMouse.pressed?"blue":normalColor
    width: (calendar.width - 20 - 60)/7
    height: (dateGrid.height - (dateLabels.rows - 1)*10)/dateLabels.rows
    
    Text {
     id: dateText
     color: highLighted?"yellow":"black"
     anchors.centerIn: parent
     text: index + 1 - firstDay
     opacity: (index < firstDay) ? 0 : 1
     font.bold: isToday(index - firstDay)  || highLighted
    }
    
    MouseArea {
     id: dateMouse
     anchors.fill: parent
     onClicked: {
      var clickedDate = new Date( showDate.getFullYear(), showDate.getMonth() + 1, index + 1 - firstDay)
      console.log(Qt.formatDate(clickedDate, "dd/mm/yyyy"))
      if (dateGrid.currentActive != -1) {
       // unselect it
       repeater.itemAt(dateGrid.currentActive).highLighted = false;
      }
    
      if (!isToday(index - firstDay)){
       highLighted = true
       dateGrid.currentActive = index
      }
     }
    }
    

    }
    }
    }
    }

    @



  • Thank you sir,
    Whatever you have said,its right...Ya i have been working in Qml for quite 1 and half month only.....Not bit inexperienced..more inexperienced.....again problem arises...if i clicked new date means,it becomes yellow and the date becomes inisible, its showing correct date...But after clicking another date,previous clicked date too in same yellow colr and clicked date becomes invisible....what can i do?I'm trying sir....



  • I don´t get it, it works here. Here my whole file
    @
    import QtQuick 1.0

    Rectangle {
    id: calendar
    width: 400; height: 300
    color: "#303030"
    property date today: new Date()
    property date showDate: new Date()
    property int daysInMonth: new Date(showDate.getFullYear(), showDate.getMonth() + 1, 0).getDate()
    property int firstDay: new Date(showDate.getFullYear(), showDate.getMonth(), 1).getDay()

    Item {
        id:title
        anchors.top: parent.top
        anchors.topMargin: 10
        width: parent.width
        height: childrenRect.height
    
        Image {
            id:monthright
            source: "Images/previous.png"
            anchors.left: parent.left
            anchors.leftMargin: 10
    
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    showDate = new Date(showDate.getFullYear(), showDate.getMonth(), 0)
                }
            }
        }
        Text {
            id:month
            color: "white"
            text: Qt.formatDateTime(showDate, "MMMM")
            font.bold: true
            anchors.left:monthright.right
        }
        Image {
            source: "Images/next.png"
            anchors.left:month.right
            MouseArea {
                anchors.fill: parent
                onClicked:
                {
                    showDate = new Date( showDate.getFullYear(), showDate.getMonth() + 1, 1)
                    console.log(showDate)
                }
            }
        }
        Image {
            source: "Images/previous.png"
            anchors.right: yearleft.left
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    showDate = new Date(showDate.getFullYear()-1,0)
                    console.log(showDate)
    
                }
            }
        }
        Text {
            id:yearleft
            color: "white"
            text: Qt.formatDateTime(showDate, "yyyy")
            font.bold: true
            anchors.right:year.left
        }
    
        Image {
            id:year
            source: "Images/next.png"
            anchors.right: parent.right
            anchors.rightMargin: 10
    
            MouseArea {
                anchors.fill: parent
                onClicked:
                {
                    showDate = new Date(showDate.getFullYear()+1, 1)
                    //   boxtext.text=new Date
                    console.log(showDate)
                }
            }
        }
    }
    
    function isToday(index) {
        if (today.getFullYear() != showDate.getFullYear())
            return false;
        if (today.getMonth() != showDate.getMonth())
            return false;
    
        return (index === today.getDate() - 1)
    }
    
    Item {
        id: dateLabels
        anchors.top: title.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 10
    
        height: calendar.height - title.height - 20 - title.anchors.topMargin
        property int rows: 6
        Item {
            id: dayLabels
            width: parent.width
            height: childrenRect.height
    
            Grid {
                columns: 7
                spacing: 10
    
                Repeater {
                    model: 7
    
                    Rectangle {
                        color: "#00ffffff"
                        width: (calendar.width - 20 - 60)/7
                        height: childrenRect.height
    
                        Text {
                            color: "#00000C"
                            // Qt dates (for formatting) and JavaScript dates use different ranges
                            // (1-7 and 0-6 respectively), so we add 1 to the day number.
                            text: Qt.formatDate(new Date(showDate.getFullYear(), showDate.getMonth(), index - firstDay +1), "ddd");
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                    }
                }
            }
        }
    

    @
    rest in next reply, does not fit on one reply



  • @
    Item {
    id: dateGrid
    width: parent.width
    anchors.top: dayLabels.bottom
    anchors.topMargin: 5
    anchors.bottom: parent.bottom
    property int currentActive: -1
    Grid {
    columns: 7
    rows: dateLabels.rows
    spacing: 10

                Repeater {
                    id: repeater
                    model: firstDay + daysInMonth
                    Rectangle {
                        property bool highLighted: false
                        property color normalColor
    
                        Component.onCompleted: {
                            if (index < firstDay)
                                normalColor = calendar.color="green";
    
                            else
                            {
                                if(isToday(index-firstDay))
                                    normalColor = "yellow";
                                else
                                    normalColor ="#eeeeee"
                            }
                        }
                        color: dateMouse.pressed?"blue":(highLighted?"grey":normalColor)
                        width: (calendar.width - 20 - 60)/7
                        height: (dateGrid.height - (dateLabels.rows - 1)*10)/dateLabels.rows
    
                        Text {
                            id: dateText
                            color: highLighted?"yellow":"black"
                            anchors.centerIn: parent
                            text: index + 1 - firstDay
                            opacity: (index < firstDay) ? 0 : 1
                            font.bold: isToday(index - firstDay)  || highLighted
                        }
    
                        MouseArea {
                            id: dateMouse
                            enabled: index >= firstDay
                            anchors.fill: parent
                            onClicked: {
                                var clickedDate = new Date( showDate.getFullYear(), showDate.getMonth() + 1, index + 1 - firstDay)
                                console.log(Qt.formatDate(clickedDate, "dd/MM/yyyy"))
                                if (dateGrid.currentActive != -1) {
                                    // unselect it
                                    repeater.itemAt(dateGrid.currentActive).highLighted = false;
                                }
    
                                if (!isToday(index - firstDay)){
                                    highLighted = true
                                    dateGrid.currentActive = index
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    }
    @



  • Thank you very much sir..Its worked.....thanks for sharing your knowledge...Very pleased for your help..



  • Glad to help, if all is done, please close all your topics about the calander with [Solved] in front of the title. I believe you posted three of them.



  • Hey, thank you for this very helpful thread, that's a good starting base for a QML calendar.
    Here is the same version using more modern layouts :
    @import QtQuick 2.1
    import QtQuick.Layouts 1.0

    Rectangle {
    id: calendar
    width: 400; height: 300
    color: "#303030"
    property date today: new Date()
    property date showDate: new Date()
    property int daysInMonth: new Date(showDate.getFullYear(), showDate.getMonth() + 1, 0).getDate()
    property int firstDay: new Date(showDate.getFullYear(), showDate.getMonth(), 1).getDay()

    Item {
        id:title
        anchors.top: parent.top
        anchors.topMargin: 10
        width: parent.width
        height: childrenRect.height
    
        Image {
            id:monthright
            source: "Images/calendar.png"
            anchors.left: parent.left
            anchors.leftMargin: 10
    
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    showDate = new Date(showDate.getFullYear(), showDate.getMonth(), 0)
                }
            }
        }
        Text {
            id:month
            color: "white"
            text: Qt.formatDateTime(showDate, "MMMM")
            font.bold: true
            anchors.left:monthright.right
        }
        Image {
            source: "Images/next.png"
            anchors.left:month.right
            MouseArea {
                anchors.fill: parent
                onClicked:
                {
                    showDate = new Date( showDate.getFullYear(), showDate.getMonth() + 1, 1)
                    console.log(showDate)
                }
            }
        }
        Image {
            source: "Images/calendar.png"
            anchors.right: yearleft.left
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    showDate = new Date(showDate.getFullYear()-1,0)
                    console.log(showDate)
    
                }
            }
        }
        Text {
            id:yearleft
            color: "white"
            text: Qt.formatDateTime(showDate, "yyyy")
            font.bold: true
            anchors.right:year.left
        }
    
        Image {
            id:year
            source: "Images/next.png"
            anchors.right: parent.right
            anchors.rightMargin: 10
    
            MouseArea {
                anchors.fill: parent
                onClicked:
                {
                    showDate = new Date(showDate.getFullYear()+1, 1)
                    //   boxtext.text=new Date
                    console.log(showDate)
                }
            }
        }
    }
    
    function isToday(index) {
        if (today.getFullYear() != showDate.getFullYear())
            return false;
        if (today.getMonth() != showDate.getMonth())
            return false;
    
        return (index === today.getDate() - 1)
    }
    
    Item {
        id: dateLabels
        anchors.top: title.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 10
    
        height: calendar.height - title.height - 20 - title.anchors.topMargin
        property int rows: 6
        Item {
            id: dayLabels
            width: parent.width
            height: childrenRect.height
    
            GridLayout {
                columns: 7
                columnSpacing: 10
                rowSpacing: 10
                width: parent.width
    
                Repeater {
                    model: 7
    
                    Rectangle {
    
                        color: "#00ffffff"
                        Layout.preferredWidth: (calendar.width - 20 - 60)/7
                        Layout.preferredHeight: childrenRect.height
                        Layout.fillWidth: true
                        Layout.fillHeight: true
    
                        Text {
                            color: "#00000C"
                            // Qt dates (for formatting) and JavaScript dates use different ranges
                            // (1-7 and 0-6 respectively), so we add 1 to the day number.
                            text: Qt.formatDate(new Date(showDate.getFullYear(), showDate.getMonth(), index - firstDay +1), "ddd");
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                    }
                }
            }
        }
    

    @

    See next post for the rest



  • @ Item {
    id: dateGrid
    width: parent.width
    anchors.top: dayLabels.bottom
    anchors.topMargin: 5
    anchors.bottom: parent.bottom
    property int currentActive: -1
    GridLayout {
    columns: 7
    width: parent.width
    height: parent.height
    columnSpacing: 10
    rowSpacing: 10

                      Repeater {
                          id: repeater
                          model: firstDay + daysInMonth
                          Rectangle {
                              property bool highLighted: false
                              property color normalColor
    
                              Component.onCompleted: {
                                  if (index < firstDay)
                                      normalColor = calendar.color="green";
    
                                  else
                                  {
                                      if(isToday(index-firstDay))
                                          normalColor = "yellow";
                                      else
                                          normalColor ="#eeeeee"
                                  }
                              }
                              color: dateMouse.pressed?"blue":(highLighted?"grey":normalColor)
                              Layout.preferredWidth: (calendar.width - 20 - 60)/7
                              Layout.preferredHeight: (dateGrid.height - (dateLabels.rows - 1)*10)/dateLabels.rows
                              Layout.fillWidth: true
                              Layout.fillHeight: true
    
                              Text {
                                  id: dateText
                                  color: highLighted?"yellow":"black"
                                  anchors.centerIn: parent
                                  text: index + 1 - firstDay
                                  opacity: (index < firstDay) ? 0 : 1
                                  font.bold: isToday(index - firstDay)  || highLighted
                              }
    
                              MouseArea {
                                  id: dateMouse
                                  enabled: index >= firstDay
                                  anchors.fill: parent
                                  onClicked: {
                                      var clickedDate = new Date( showDate.getFullYear(), showDate.getMonth() + 1, index + 1 - firstDay)
                                      console.log(Qt.formatDate(clickedDate, "dd/MM/yyyy"))
                                      if (dateGrid.currentActive != -1) {
                                          // unselect it
                                          repeater.itemAt(dateGrid.currentActive).highLighted = false;
                                      }
    
                                      if (!isToday(index - firstDay)){
                                          highLighted = true
                                          dateGrid.currentActive = index
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
          }
      }@

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.