Bonjour,

Je travail actuellement sur la réalisation d'un calendrier, que j'ai presque fini a un détail près.

Pour l'affichage des jours j'ai créé un QGridLayout que je remplis de QLabel. Le problème se pose lorsque je navigue d'un mois à l'autre. Le QGridLayout n'est pas vidé et la liste des nouveau jours se superposent sur les précédents.

J'ai fait des recherches et essayé plusieurs méthodes je pense donc que le problème est plus compliqué que je ne le pense. Je vous montre donc tout le code.

J'ai créé une class Calendrier qui hérite de QVBoxLayout.

Calendrier.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef CALENDRIER_H
#define CALENDRIER_H
 
#include<QObject>
 
#include<QBoxLayout>
#include<QHBoxLayout>
#include<QVBoxLayout>
#include<QGridLayout>
 
#include<QWidget>
#include<QComboBox>
#include<QPushButton>
#include<QLabel>
#include<QStringList>
 
#include<QDate>
 
#include<QMouseEvent>
 
#include <QMessageBox>
 
class Calendrier:public QVBoxLayout{
    Q_OBJECT
public:
    Calendrier();        
 
public slots:
    void InitListeJour();
    void clicSuivant();
    void clicPrecedent();
 
private:
    void InitComponents();    
    QLabel* calculJour(int pJour, int pMois, int pAnnee);
    QLabel* calculJour(QDate pDate);
 
    QLabel *lbl;
 
    QHBoxLayout selecteurDate;    
    QGridLayout affichage;
 
    QComboBox mois;
    QComboBox annee;
 
    QPushButton suivant;
    QPushButton precedent;
};
#endif // CALENDRIER_H
Calendrier.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include"Calendrier.h"
 
using namespace std;
 
Calendrier::Calendrier(): QVBoxLayout(){
    InitComponents();
 
    this->addLayout(&selecteurDate);
    this->addLayout(&affichage);
 
    suivant.setFixedWidth(25);
    precedent.setFixedWidth(25);
 
    selecteurDate.addWidget(&precedent);
    selecteurDate.addWidget(&mois);
    selecteurDate.addWidget(&annee);
    selecteurDate.addWidget(&suivant);
}
 
void Calendrier::InitComponents(){
    lbl = new QLabel[42];
 
    suivant.setText("->");
    precedent.setText("<-");
 
    QStringList listeMois;
    listeMois << tr("Janvier") << tr("Février") << tr("Mars") << tr("Avril") << tr("Mai") << tr("Juin")
              << tr("Juillet") << tr("Aout") << tr("Septembre") << tr("Octobre") << tr("Novembre") << tr("Décembre") ;
    mois.addItems(listeMois);
 
    for(int i = 2010; i <= 2100; i++)
        annee.addItem(QString::number(i));
 
    affichage.addWidget(new QLabel(tr("Lu")),0,0);
    affichage.addWidget(new QLabel(tr("Ma")),0,1);
    affichage.addWidget(new QLabel(tr("Me")),0,2);
    affichage.addWidget(new QLabel(tr("Je")),0,3);
    affichage.addWidget(new QLabel(tr("Ve")),0,4);
    affichage.addWidget(new QLabel(tr("Sa")),0,5);
    affichage.addWidget(new QLabel(tr("Di")),0,6);
 
    QDate date = QDate::currentDate();
    annee.setCurrentIndex(annee.findText(QString::number(date.year())));
    mois.setCurrentIndex(date.month()-1);
 
    InitListeJour();
 
    connect(&suivant, SIGNAL(clicked()),SLOT(clicSuivant()));
    connect(&precedent, SIGNAL(clicked()),SLOT(clicPrecedent()));
    connect(&mois,SIGNAL(currentIndexChanged(int)),SLOT(InitListeJour()));
    connect(&annee,SIGNAL(currentIndexChanged(int)),SLOT(InitListeJour()));
}
 
QLabel* Calendrier::calculJour(int pJour, int pMois, int pAnnee){
    //!pJour est inutilisée
    QLabel *listeJour = new QLabel[42];
    QDate date(pAnnee,pMois,1);
 
    int premierJour(date.dayOfWeek()-1);//-1 car le premier indice du tableau est 0.
    int dernierJourPre((date.addMonths(-1)).daysInMonth());
 
    //Insertion des jours du mois précédent à partir de l'indice précédent du premierJour.
    for(int i = premierJour-1; i>=0; i--)
        listeJour[i].setText(QString::number(dernierJourPre--));
 
    int j = 1;//Sert à afficher les jours du mois en cours.
    for(int i = premierJour; i < 42 ;i++)
    {
        if(j == QDate::currentDate().day()
                && mois.currentIndex() == QDate::currentDate().month()-1
                && annee.currentText() == QString::number(QDate::currentDate().year()))
            listeJour[i].setText("<font color=\"red\">"+ QString::number(j) +"<\\font>");
            else
                listeJour[i].setText(QString::number(j));
        //Si on arrive à la fin du mois en cours on passe j à 1 pour afficher les jours du mois suivant.
        if(j == date.daysInMonth())
            j=1;
        else
            j++;
    }
    return listeJour;
}
 
QLabel* Calendrier::calculJour(QDate pDate){
    return calculJour(pDate.year(),pDate.month(),pDate.day());
}
 
//SLOT personalisés.
 
//Affiche la liste des jours dans le QGridLayout affichage.
void Calendrier::InitListeJour(){
    lbl = calculJour(QDate::currentDate().day(),mois.currentIndex()+1,annee.currentText().toInt());
    int r(1),c(0);//r=ligne, c=colonne (La ligne 0 contient l'intitulé des jours).
 
    for(int i = 0; i < 42; i++)
    {
        affichage.addWidget(&lbl[i],r,c);
        c++;
        if(c>6){
            c=0;
            r++;
        }
    }
}
 
void Calendrier::clicSuivant(){
    int indMois = mois.currentIndex();
    int indAnnee = annee.currentIndex();
    indMois++;
 
    //Si l'indice du mois est égal à 12 il faut afficher le mois de janvier (indice 0)
    //et incrémenter l'année si elle est différente de la dernière.
    if(indMois == 12 && indAnnee != 90)
    {
        mois.setCurrentIndex(0);
        indAnnee = annee.currentIndex();
        annee.setCurrentIndex(++indAnnee);
    }
    else if(indMois <= 11 )//Sinon on affiche le mois incrémenté si son indice est <= 11.
        mois.setCurrentIndex(indMois);
}
 
void Calendrier::clicPrecedent(){
    int indMois = mois.currentIndex();
    int indAnnee = annee.currentIndex();
    indMois--;
 
    //Si l'indice du mois est de - 1 il faut afficher le mois de décembre (indice 11)
    //et décrémenter l'annnée si elle est différente de la première.
    if(indMois == -1 && indAnnee != 0)
    {
        mois.setCurrentIndex(11);
        indAnnee = annee.currentIndex();
        annee.setCurrentIndex(--indAnnee);
    }
    else if(indMois >= 0)//Sinon on affiche le mois décrémenté si son indice est >= à 0.
        mois.setCurrentIndex(indMois);
}
La fonction en charge d'afficher les QLabel dans le QGridLayout est InitListeJour.

Un autre problème: dans la fonction calculeJour je déclare un pointeur que je ne supprime et qui fait donc planter le programme à la fermeture. Comme je le retourne à la fin de la fonction je ne peux pas faire de delete donc auriez-vous une idée? EDIT: Je devrais m'en sortir avec ça

Sinon si vous avez des idées d'améliorations je suis preneur.

Merci de votre aide.