IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Collection d'objets polymorphes: Comment faire ?


Sujet :

Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut Collection d'objets polymorphes: Comment faire ?
    Bonjour,
    je veux faire un composant de type collection qui permet de faire des stats.
    Au final, je voudrais que lorsqu'un utilisateur ajoute un item, il puisse choisir entre un objet type Gauss, ou un objet type poisson.

    Avant d'aller plus loin, voici mes classes.
    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
    139
    140
    141
    142
    143
    144
    145
    type
      TStat_Gene = class(TComponent)
      private
        FGauss : TLoiGauss;
        FPoisson :  TLoiPoisson;
     
        //acesseur
        function GetBorneMin: statistique.TGestionBorne;
        procedure SetBorneMin(val: statistique.TGestionBorne);
        function GetBorneMax: statistique.TGestionBorne;
        procedure SetBorneMax(val: statistique.TGestionBorne);
        function GetCapaMin: double;
        procedure SetCapaMin(val: double);
        function GetCapaMax: double;
        procedure SetCapaMax(val: double);
        function GetLotMin: double;
        procedure SetLotMin(val: double);
        function GetLotMax: double;
        procedure SetLotMax(val: double);
        function GetSpecMin: double;
        procedure SetSpecMin(val: double);
        function GetSpecMax: double;
        procedure SetSpecMax(val: double);
        function GetCp: double;
        function GetCpl: double;
        function GetCph: double;
        function GetCpk: double;
        function GetMoyenne: Extended;
        function GetSigma: Extended;
        function GetNbMesure: Extended;
        function GetNbMesureConforme: Extended;
        function GetN: Extended;
        procedure SetN(val : Extended);
        function GetP: Extended;
        procedure SetP(val : Extended);
        function GetQ: Extended;
        procedure SetQ(val : Extended);
        function GetM: Extended;
        procedure SetM(val : Extended);
        function GetEsperance: Extended;
        function GetVariance:Extended;
        function GetProbabilite: Extended;
        function GetProbabilitePoisson: Extended;
        function GetTypedeCalcul: statistique.TTypeCalcul;
        procedure SetTypedeCalcul(val: statistique.TTypeCalcul);
        //fin acesseur
        procedure CalculPoissonVarEsp;
     
     
      published
        ///<alias>Borne Minimal</alias>
        property BorneMin: statistique.TGestionBorne Read GetBorneMin Write SetBorneMin default Inclus;
        ///<alias>Borne Maximal</alias>
        property BorneMax: statistique.TGestionBorne Read GetBorneMax Write SetBorneMax default Inclus;
        ///<alias>Capabilité Minimal</alias>
        property CapaMin: double Read GetCapaMin Write SetCapaMin;
        ///<alias>Capabilité Maximal</alias>
        property CapaMax: double Read GetCapaMax Write SetCapaMax;
        ///<alias>Lot Minimal</alias>
        property LotMin: double Read GetLotMin Write SetLotMin;
        ///<alias>Lot Maximal</alias>
        property LotMax: double Read GetLotMax Write SetLotMax;
        ///<alias>Spec Minimal</alias>
        property SpecMin: double Read GetSpecMin Write SetSpecMin;
        ///<alias>Spec Maximal</alias>
        property SpecMax: double Read GetSpecMax Write SetSpecMax;
        ///<alias>Cp</alias>
        property Cp : Double Read GetCp;
        ///<alias>Cpl</alias>
        property Cpl : Double Read GetCpl;
        ///<alias>Cph</alias>
        property Cph : Double Read GetCph;
        ///<alias>Cpk</alias>
        property Cpk : Double Read GetCpk;
        ///<alias>Moyenne</alias>
        property Moyenne : Extended Read GetMoyenne;
        ///<alias>Sigma</alias>
        property Sigma : Extended Read GetSigma;
        ///<alias>NbMesure</alias>
        property NombreMessure : Extended Read GetNbMesure;
        ///<alias>NbMesureConforme</alias>
        property NombreMessureConforme : Extended Read GetNbMesureConforme;
        ///<alias>N</alias>
        property N : Extended Read GetN Write SetN;
        ///<alias>P</alias>
        property P : Extended Read GetP Write SetP;
        ///<alias>Q</alias>
        property Q : Extended Read GetQ Write SetQ;
        ///<alias>M</alias>
        property M : Extended Read GetM Write SetM;
        ///<alias>Esperance</alias>
        property Esperance : Extended Read GetEsperance;
        ///<alias>Variance</alias>
        property Variance : Extended Read GetVariance;
        ///<alias>Probabilité</alias>
        property Probabilite : Extended Read GetProbabilite;
        ///<alias>Probabilité Poisson</alias>
        property ProbabilitePoisson : Extended Read GetProbabilitePoisson;
        ///<alias>Type de Calcul</alias>
        property TypedeCalcul: statistique.TTypeCalcul
          Read GetTypedeCalcul Write SetTypedeCalcul default Spec;    
      public
        constructor Create(Aowner : TComponent);override;
        procedure InsertionMesure(mesure : double);
        procedure Proba(val : extended);
        procedure RemiseAZéroComposant;
        procedure RemiseAZéroResultat;
      end;
     
      TCmpStatItem = class(TCollectionItem)
      private
        FName : String;
        FStat : TStat_Gene;
        procedure SetName(const Value:String);
     
      protected
        Function GetDisplayName: String; Override;
      published
        property Name : string read FName write SetName;
        property Stat : TStat_Gene read FStat;
      end;
     
      TCmpStats = class;
     
      TspStat = Class(TComponent)
        private
          FItems: TCmpStats;
          procedure SetItems(value : TCmpStats);
        public
          constructor Create(AOwner : TComponent); override;
          destructor Destroy; override;
        published
          property Item: TCmpStats read FItems write SetItems;
      End;
     
      TCmpStats = class( TOwnedCollection)
        private
          FComponent : TspStat;
          function GetItem(Index: Integer): TCmpStatItem;
          procedure SetItem(index: Integer; Value : TCmpStatItem);
        public
          constructor Create(Stat : TspStat);
          function Add : TCmpStatItem;
          property Items[Index : Integer]: TCmpStatItem read GetItem write SetItem; default;
      end;
    Voici les problèmes que je rencontre :
    * Je voudrais faire apparaitre les property de FStat dans l'inspecteur d'objet.
    Je me retrouve avec simplement Stat et un champs vide en face.
    Comment faire ?

    * Comment faire un Write de la Stat ?

    J'espere avoir été clair.
    Merci

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    La propriété Stat est "vide" (en fait à NIL) car l'EDI s'attend à ce que tu rattache ce champ à un objet TStat_Gene qui serait théoriquement déposé sur la fiche.

    Si tu veux avoir un objet déjà présent dès la conception alors il faut créé un objet TStat_Gene et renseigner la propriété FStat avec, tout ceci au niveau du constructeur de TCmpStatItem.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Bonjour,
    merci de ta réponse.

    Voici le constructeur que je viens de rajouter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    constructor TCmpStatItem.create;
    begin
      FStat := TStat_Gene.Create(nil);
      FStat.RemiseAZéroComposant;
    end;
    Malheureusement, ça ne change rien.
    J'ai poser des points d'arrêts dans la fonction. Mais quand je compile, ils deviennent verts, comme si je les avais mis devant un commentaire.

    Du coup j'arrive pas a débugé et a voir ce qui ce passe.

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Si je ne m'abuse là tu viens de créer un autre constructeur au lieu de le surcharger. Essayes comme ça, ça ira mieux

    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
    implementation
     
    TCmpStatItem = class(TCollectionItem)
    [...]
    public
      Constructor Create( Collection:TCollection ); override;
    end;
     
    interface
     
    Constructor TCmpStatItem.Create( Collection:TCollection );
    begin
      inherited;
      FStat := TStat_Gene.Create(nil);
      FStat.RemiseAZéroComposant;
    end;
    Première remarque plutôt que de passer NIl tu ferais mieux de passer le Owner de l'objet collection qui possède l'item (avec un peu de cast) afin que l'objet ne soit pas "perdu".

    Seconde remarque les caractères accentués pour les identificateurs (noms de classes, variables, fonctions, méthodes, etc...) il vaut mieux éviter

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Oui, j'ai volontairement créer un constructeur... j'avais mal penser la chose.
    Mea culpa.

    Au rayon des bonnes nouvelles, mes points d'arrêts fonctionne.
    Mauvaise nouvelle, l'inspecteur d'objet n'as pas changer.
    Est ce qu'il faut que je fasse un screenshoot de mon inspecteur d'objet ou je suis suffisament clair ??

    Je regarde comment fonctionne les cast sous delphi.
    Et je change les "é" dans mes fonctions.
    Merci, je te tiens au courants des avancers.

    Par contre, j'ai regarder comment était fait un TChart, et j'ai été très surpris de voir que le composant n'est composé que de property, avec des sortes de if et else entre certaine.
    Est ce que quelqu'un sais comment ça marche ?

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Je vient de faire le cast et ça marche
    Je comprend mieux pourquoi tu disait que mon objet était perdu.
    Merci

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sapin Voir le message
    Par contre, j'ai regarder comment était fait un TChart, et j'ai été très surpris de voir que le composant n'est composé que de property, avec des sortes de if et else entre certaine.
    Est ce que quelqu'un sais comment ça marche ?
    Je te rassures un truc aussi compliqué que le TChart ne fonctionne pas qu'en déclarant quelques propriétés et en cliquant des doigts

    En outre les IF que tu vois sont ce qu'on appelle des conditions de compilations, je te conseilles de faire un F1 là dessus pour mieux comprendre.

    Si tu regardes l'implémentation d'un TChart tu verras qu'il hérite d'une autre classe (certainement un TCustomChart avec D7 j'ai pas les sources de ce composant), je te le donne en mille c'est lui qui fait tout

    En général les composants fonctionnent tous sur le principe d'avoir un TCustomXXX qui fournit la vraie implémentation ainsi que les diverses propriétés mais déclarées protected et le composant final TXXX qui hérite de TCustomXXX et qui ne fait que publier les propriétés protégées du composant.
    Pourquoi faire ça et bien pour permettre aux développeur de pouvoir créer de nouveaux composants plus facilement dans le sens où c'est le composant final qui décide quelles sont les propriétés publiques ou publiées d'un composant plutôt d'avoir des propriétés visibles de l'extérieur mais qui ne servent à rien voire peuvent être dangereuses si l'utilisateur tente de modifier ses valeurs.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    J'avais bien vu que TChart héritait de TCustomChart.
    Faut-il que je repense la création de mon composant pour qu'il soit comme un TChart avec la sélection automatique des proprety a afficher ?
    Je rappel qu'a terme, je souhaite des items génériques, et donc avec des property pouvant varier selon le choix de l'utilisateur.

    Ces conditions de compilation peuvent régler ce genre de problème non ?

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Bonjour,

    je reprend ce topic car je me trouve face à un problème dont je ne voit pas d'issue.
    Maintenant que j'ai réussi a faire une collection, je voudrai laisser le choix a l'utilisateur du type de loi qu'il souhaite utilisé (loi de gauss où loi de poisson pour le moment).
    J'ai donc rajouté un nouveau champs permettant la saisie du type de loi, pas de soucis la dessus. Mon problème vient plus de la classe item, car je doit avoir un sorte de polymorphisme et que je ne sais pas comment géré les propriété, puisqu'elle dépende du type de loi choisi.

    Dans le code donné précédemment, on peut voir que j'ai défini les property dans TStatGene, si je remet les property dans les classe TGauss et TPoisson, et que je remplace mes FGauss et FPoisson par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FLoiGenerique : TPersistant
    est ce que ca pourrai marcher ?

    Ou du moins, est ce que je suis sur la bonne voie.

    Merci, j'attends vos conseils.

    EDIT :
    pour etre plus concret, voici mon code.
    Est ce que la généricité est bien géré ?
    Est ce que je ne perd pas mes objets dans les create ?
    car evidement, ça ne fonctionne pas

    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
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    type
      TTypeDeStat = (Gauss, Poisson, Laplace, Binomiale);
     
      TStat_Gene = class(TComponent)
      public
        FLoiGenerique : TPersistent;
        constructor Create(Aowner : TComponent);overload;override;
        constructor Create(Aowner : TComponent; TypeLoi : TTypeDeStat);overload;
      end;
     
      TCmpStatItem = class(TCollectionItem)
      private
        FTypeStat : TTypeDeStat;
        FName : String;
        FStat : TStat_Gene;
        procedure SetName(const Value:String);
      protected
        Function GetDisplayName: String; Override;
      published
        property Name : string read FName write SetName;
        property Stat : TStat_Gene read FStat;
        property Loi : TTypeDeStat read FTypeStat write FTypeStat default Gauss;
      public
        Constructor Create( Collection:TCollection ); override;
      end;
     
      TCmpStats = class;
     
      TspStat = Class(TComponent)
        private
          FItems: TCmpStats;
          procedure SetItems(value : TCmpStats);
        public
          constructor Create(AOwner : TComponent); override;
          destructor Destroy; override;
        published
          property Item: TCmpStats read FItems write SetItems;
      End;
     
      TCmpStats = class( TOwnedCollection)
        private
          FComponent : TspStat;
          function GetItem(Index: Integer): TCmpStatItem;
          procedure SetItem(index: Integer; Value : TCmpStatItem);
        public
          constructor Create(Stat : TspStat);
          function Add : TCmpStatItem;
          property Items[Index : Integer]: TCmpStatItem read GetItem write SetItem; default;
      end;
     
     
     
    procedure Register;
     
    implementation
     
    procedure Register;
    begin
      RegisterComponents('Statistique', [TspStat]);
    end;
     
     
    ////////////////////////////////////////////////////////////////////////////////
    //// TCmpStatsItem
    ////////////////////////////////////////////////////////////////////////////////
    function TCmpStatItem.GetDisplayName:string;
    begin
      Result := FName;
      if Result='' then Result:= inherited GetDisplayName;
    end;
     
    procedure TCmpStatItem.SetName(const Value: string);
    begin
      if Value<>'' then FName := Value
      else FName := 'Indéfini';
    end;
     
    Constructor TCmpStatItem.Create( Collection:TCollection );
    begin
      inherited;
      FStat := TStat_Gene.Create(Tcomponent(Collection.Owner));
      FName := 'test';
    end;
     
     
    ////////////////////////////////////////////////////////////////////////////////
    ////Fin TCmpStatsItem
    ////////////////////////////////////////////////////////////////////////////////
     
    ////////////////////////////////////////////////////////////////////////////////
    //// TCmpStats
    ////////////////////////////////////////////////////////////////////////////////
    function TCmpStats.Add : TCmpStatItem;
    begin
      Result := TCmpStatItem(inherited Add);
    end;
     
    constructor TCmpStats.Create(Stat: TspStat);
    begin
      inherited Create(Stat,TCmpStatItem);
      FComponent := Stat;
    end;
     
    procedure TCmpStats.SetItem(index: Integer; Value: TCmpStatItem);
    begin
      inherited SetItem(index,Value);
    end;
     
    function TCmpStats.GetItem(Index: Integer): TCmpStatItem;
    begin
      Result := TCmpStatItem(inherited GetItem(Index));
    end;
    ////////////////////////////////////////////////////////////////////////////////
    //// Fin TCmpStats
    ////////////////////////////////////////////////////////////////////////////////
     
    ////////////////////////////////////////////////////////////////////////////////
    //// TspStat
    ////////////////////////////////////////////////////////////////////////////////
    Constructor TspStat.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FItems := TCmpStats.Create(Self);
    end;
     
    Destructor TspStat.Destroy;
    begin
      FItems.Free;
      inherited Destroy;
    end;
     
    procedure TspStat.SetItems(value: TCmpStats);
    begin
      FItems.Assign(value);
    end;
    ////////////////////////////////////////////////////////////////////////////////
    //// Fin TspStat
    ////////////////////////////////////////////////////////////////////////////////
     
    ////////////////////////////////////////////////////////////////////////////////
    /// Fin TStat_Gene
    ////////////////////////////////////////////////////////////////////////////////
    //constructeur
    constructor TStat_Gene.create(Aowner : TComponent);
    var
      Spec : TSpecAndCara;
    begin
      inherited Create(Aowner);
      Spec := TSpecAndCara.Create;
      FLoiGenerique :=  TPersistent(TloiGauss.create(Spec));
    end;
     
    constructor TStat_Gene.create(Aowner : TComponent; TypeLoi : TTypeDeStat);
    var
      Spec : TSpecAndCara;
    begin
      inherited Create(Aowner);
      // on regarde le type de loi voulu
      case TypeLoi of
        Gauss: FLoiGenerique := TPersistent(TloiGauss.create(Spec)) ;
        Poisson: FLoiGenerique := TPersistent(TLoiPoisson.create(Spec));
        Laplace: FLoiGenerique := TPersistent(TLoiLaplace.Create(Spec));
        Binomiale: FLoiGenerique := TPersistent(TLoiBinomiale.Create(Spec));
      end;
    end;
    //fin constructeur
     
     
     
    ////////////////////////////////////////////////////////////////////////////////
    /// Fin TStat_Gene
    ////////////////////////////////////////////////////////////////////////////////
    end.

  10. #10
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Hello Sapin.

    Alors pour moi il faut que tu définisse un SetTypeStat au niveau de l'item implémenté de la façon suivante :

    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
    interface
      TCmpStatItem = class(TCollectionItem)
        [...]
      protected
       procedure SetTypeStat( Value: TTypeDeStat );
      publshed
       property Loi : TTypeDeStat read FTypeStat write SetTypeStat default Gauss;
      end;
     
    implementation
     
    procedure SetTypeStat( Value: TTypeDeStat );
    begin
      // on a changé le type de loi
      if Value <> FTypeStat then
      begin
        // si une loi précédente existante, la détruite
        if Assigned( FStat ) then
          FreeAndNil( FStat );
     
        FTypeStat := Value;
        FStat := TStat_Gene.Create(Tcomponent(Collection.Owner), FTypeStat);
      end;
    end;
    PS : au niveau TStat_Gene.create(Aowner : TComponent; TypeLoi : TTypeDeStat), si chaque loi descend bien de TPersistent alors le cast explicite n'est pas nécessaire.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Effectivement, mon problème était que ma classe la plus haute n'héritai pas de TPersistent.
    J'avais trouver mon erreur hier soir, mais j'ai oublié de le signaler

    Merci

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Re bonjour,

    J'ai encore un problème avec ma collection d'objet polymorphe (comme d'habitude ).

    Je viens de me rendre compte que les valeurs que je mettai dans l'inspecteur d'objet était remise a zéro lorsque je compile (enfin, que j'appuie sur F9, car la notion de compilation des composants reste un peu flou pour moi).

    Je ne m'attendais pas à ce genre de probleme, car tous hérite de TPersistant.

    Est-ce qu'il est possible que lorsque j'appuye sur F9, il repasse par les create respectif et les mise à zéro des valeurs ?
    Ou bien est ce parce que je rattache mal mes items ?
    En d'autre termes, comment conservé les valeurs passé dans l'inspecteur d'objet?


    Autre question, je n'arrive pas a voir mes Items en mode debug, ce qui me rend la compréhension de mon problème très difficiles. Avez-vous une technique particulière pour voir, par exemple, l'item 1 de la collection ?

    Merci, et pardon vous faire perdre un peu de votre temps..

  13. #13
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Pour le debugger à partir de l'inspecteur (CTRL+F7) tu peux entrer une ligne de commande à exécuter à la volée en exécution.

    Tu peux notamment, si tu as une v1 pointant vers ton composant faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TMonCollectionItem( v1.Collection[0] )
    Tu auras alors accès aux propriétés de l'item 0 de ta collection.

    Pour le reste je ne sais pas exactement il faudrait que je teste mais une question me taraude depuis le début. Comment vas-tu utiliser la collection par la suite ?

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    ReBonjour Aka Guymelef,
    pour l'utilisation du composant, je vais faire des captures d'écran, ca sera plus simple.

    Pour mon probleme, j'ai l'impression que mon objet ce perd en cours de route, peut etre que j'ai un probleme au niveau d'un create, (la creation de FStat ou Floigenerique en particulier) mais je ne visualise pas mon erreur.

    Edit : capture d'ecran dispo.
    Telle que je l'ai pensé, pour l'utilisation ca se passe comme ca.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      spStat1.Item[0].Stat.FLoiGenerique.Operation(2);
    Avec ce l'image Sans titre, ca devrai ce derouler comme ceci

    FloiGenerique.operation(2) va dans la fonction TLoiBinomiale.operation(x) //ca c'est bon
    TloiBinomiale.operation(x) calcul la probabilité x connaisant n,p et q renseigné dans l'inspecteur d'objet. // ca marche pas, car mes n,p et q n'ont plus les valeurs renseigné, elle sont remise à zéro.

    J'espere que je suis clair

  15. #15
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Je vais essayer de voir ton problème chez moi ce soir.

    Par contre il y a un doute que je n'arrives vraiment pas à me retirer au niveau de l'utilisation après de ta collection. Si tu n'utilises que le premier item à chaque fois je ne vois pas à quoi te sers une collection sauf si chaque item va correspondre après à un traitement métier (typiquement un item par TChart).

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Normalement tous les item peuvent etre utilisés.
    Comme ceci par exemple :
    item 0 : Largeur, loi poisson.
    item 1 : Largeur, loi gauss.
    item 2 : surface, loi laplace.

    J'espere que l'on parle de la meme chose car je n'ai pas très bien compris ton exemple avec le chart.

    Sinon, au niveau purement codage, je me suis rendu compte que l'on pouvait supprimer la classe TStat_gene.
    en faisant comme ceci par exemple

    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
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    type
      TTypeDeStat = (Gauss, Poisson, Laplace, Binomiale);
     
      TCmpStatItem = class(TCollectionItem)
      private
        FTypeStat : TTypeDeStat;
        FName : String;
        FStat : TMath;
        function GetLoiGenerique: TMath;
        procedure SetName(const Value:String);
        procedure SetTypeStat(val : TTypeDeStat);
      protected
        Function GetDisplayName: String; Override;
      published
        property Name : string read FName write SetName;
        property LoiGenerique : TMath read GetLoiGenerique write FStat ;
        property Loi : TTypeDeStat read FTypeStat write SetTypeStat default Gauss;
      public
        Constructor Create( Collection:TCollection ); override;
      end;
     
      TCmpStats = class;
     
      TspStat = Class(TComponent)
        private
          FItems: TCmpStats;
          procedure SetItems(value : TCmpStats);
        public
          constructor Create(AOwner : TComponent); override;
          destructor Destroy; override;
        published
          property Item: TCmpStats read FItems write SetItems;
      End;
     
      TCmpStats = class( TOwnedCollection)
        private
          FComponent : TspStat;
          function GetItem(Index: Integer): TCmpStatItem;
          procedure SetItem(index: Integer; Value : TCmpStatItem);
        public
          constructor Create(Stat : TspStat);
          function Add : TCmpStatItem;
          property Items[Index : Integer]: TCmpStatItem read GetItem write SetItem; default;
      end;
     
     
     
    procedure Register;
     
    implementation
     
    procedure Register;
    begin
      RegisterComponents('Statistique', [TspStat]);
    end;
     
     
    ////////////////////////////////////////////////////////////////////////////////
    //// TCmpStatsItem
    ////////////////////////////////////////////////////////////////////////////////
    function TCmpStatItem.GetDisplayName:string;
    begin
      Result := FName;
      if Result='' then Result:= inherited GetDisplayName;
    end;
     
    function TCmpStatItem.GetLoiGenerique: TMath;
    begin
      Result := FStat;
    end;
     
    procedure TCmpStatItem.SetName(const Value: string);
    begin
      if Value<>'' then FName := Value
      else FName := 'Indéfini';
    end;
     
    Constructor TCmpStatItem.Create( Collection:TCollection );
    begin
      inherited create(Collection);
      SetTypeStat(Gauss);
      FStat := TLoiGauss.Create(spec);
    end;
     
    procedure TCmpStatItem.SetTypeStat(val : TTypeDeStat);
    var
      spec :TSpecAndCara;
    begin
     // si une loi précédente existante, la détruite
      if Assigned( FStat ) then
          FreeAndNil( FStat );
      FTypeStat := val;
      spec := TSpecAndCara.Create;
      case FTypeStat of
        Gauss: FStat := TloiGauss.create(Spec) ;
        Poisson: FStat := TLoiPoisson.create(Spec);
        Laplace: FStat := TLoiLaplace.Create(Spec);
        Binomiale: FStat := TLoiBinomiale.Create(Spec);
      end;
    end;
     
    ////////////////////////////////////////////////////////////////////////////////
    ////Fin TCmpStatsItem
    ////////////////////////////////////////////////////////////////////////////////
     
    ////////////////////////////////////////////////////////////////////////////////
    //// TCmpStats
    ////////////////////////////////////////////////////////////////////////////////
    function TCmpStats.Add : TCmpStatItem;
    begin
      Result := TCmpStatItem(inherited Add);
    end;
     
    constructor TCmpStats.Create(Stat: TspStat);
    begin
      inherited Create(Stat,TCmpStatItem);
      FComponent := Stat;
    end;
     
    procedure TCmpStats.SetItem(index: Integer; Value: TCmpStatItem);
    begin
      inherited SetItem(index,Value);
    end;
     
    function TCmpStats.GetItem(Index: Integer): TCmpStatItem;
    begin
      Result := TCmpStatItem(inherited GetItem(Index));
    end;
    ////////////////////////////////////////////////////////////////////////////////
    //// Fin TCmpStats
    ////////////////////////////////////////////////////////////////////////////////
     
    ////////////////////////////////////////////////////////////////////////////////
    //// TspStat
    ////////////////////////////////////////////////////////////////////////////////
    Constructor TspStat.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FItems := TCmpStats.Create(Self);
    end;
     
    Destructor TspStat.Destroy;
    begin
      FItems.Free;
      inherited Destroy;
    end;
     
    procedure TspStat.SetItems(value: TCmpStats);
    begin
      FItems.Assign(value);
    end;
    ////////////////////////////////////////////////////////////////////////////////
    //// Fin TspStat
    ////////////////////////////////////////////////////////////////////////////////
     
    end.
    Bon, je suis en train de refaire le code, donc j'ai quelque petit problèmes. Peut etre que mon probleme précédent venait de la creation de TStat_gene.

  17. #17
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Effectivement c'est déjà plus simple comme ça mais quelque chose m'intrigue car pour que cela fonctionne avec le designer il faut que le Owner FStat soit renseigné et de préférence avec le Owner de la collection. De quoi hérite TMath ?

    Autre chose à quoi sert l'objet de classe TSpecAndCara que tu passe en paramètre du constructeur de TMath ?

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Voici le code de TMaht

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      TMath = class(TPersistent)
      public
        constructor Create;virtual;
        destructor Destroy; override;
        {------------- Methode Virtuel pour permettre le polymorphisme-------------}
        procedure Operation(x: extended) ; virtual; abstract;
        procedure Initialisation;overload; virtual; abstract;
        procedure Initialisation(spec : TSpecAndCara); overload;virtual; abstract;
      end;
    Avant de penser au collection, specetcara me servait à paramétrer les lois de gauss et de laplace.
    Mais je pense que ca devrai disparaitre, vu que maintenant ils en heritent.

    en pièce jointe mon diagramme de classe qui permettra d'y voir plus clair.

  19. #19
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Comme promis voici le résultat de mes pérégrinations :

    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
    139
    140
    141
    142
    143
    144
    145
    unit Collection_Unit;
     
    interface
    uses Classes;
     
    type
      TItemType = ( itUnknown, itClassA, itClassB );
     
      TRootClass = class( TPersistent )
      protected
       FOwner: TPersistent;
       function GetOwner: TPersistent; override;
      public
       Constructor Create( AOwner: TPersistent );
      end;
     
      TClassA = class( TRootClass )
      private
        FAbcisse: Integer;
        FOrdonnee: Integer;
      published
       property Abcisse: Integer read FAbcisse write FAbcisse;
       property Ordonnee: Integer read FOrdonnee write FOrdonnee;
      end;
     
      TClassB = class( TRootClass )
      private
        FTexte: String;
      published
       property Texte: String read FTexte write FTexte;
      end;
     
      TMaCollectionItem = class( TCollectionItem )
      private
       FItemType: TItemType;
       FCompo: TRootClass;
       procedure SetItemType(const Value: TItemType);
      public
       Constructor Create( Collection:TCollection ); override;
      published
       property ItemType: TItemType read FItemType write SetItemType default itUnknown;
       property Compo: TRootClass read FCompo write FCompo;
      end;
     
      TMaCollection = class( TOwnedCollection )
      end;
     
      TMonComposant = class( TComponent )
      private
        FCollection: TMaCollection;
        procedure SetCollection(const Value: TMaCollection);
      public
       Constructor Create( AOwner: TComponent ); override;
       Destructor Destroy; override;
     
      published
       property Collection: TMaCollection read FCollection write SetCollection;
      end;
     
    procedure Register;
     
    implementation
    uses SysUtils, Dialogs;
     
    procedure Register;
    begin
      RegisterComponents('Samples', [TMonComposant]);
    end;
     
    { TRootClass }
     
    constructor TRootClass.Create(AOwner: TPersistent);
    begin
      inherited Create;
      FOwner := AOwner;
    end;
     
    function TRootClass.GetOwner: TPersistent;
    begin
      Result := FOwner;
    end;
     
    { TMaCollectionItem }
     
    constructor TMaCollectionItem.Create(Collection: TCollection);
    begin
      inherited;
      FCompo := NIL;
      ItemType := itUnknown;
    end;
     
    procedure TMaCollectionItem.SetItemType(const Value: TItemType);
    var
      Designer: IDesignerNotify;
    begin
      if FItemType <> Value then
      begin
        //designer
        Designer := FindRootDesigner( Self );
        //designer
     
        FItemType := Value;
        if Assigned( FCompo ) then
        begin
         //designer
         FCompo.FOwner := NIL;
         if Designer <> NIL then
          Designer.Notification( FCompo, opRemove );
         //designer
         FreeAndNil( FCompo );
        end;
     
        case FItemType of
         itClassA: FCompo := TClassA.Create( Self );
         itClassB: FCompo := TClassB.Create( Self );
        end;
     
        //designer
        if Assigned( FCompo ) then
         if Designer <> NIL then
          Designer.Notification( FCompo, opInsert );       
        //designer
      end;
    end;
     
    { TMonComposant }
     
    constructor TMonComposant.Create(AOwner: TComponent);
    begin
      inherited;
      FCollection := TMaCollection.Create( Self, TMaCollectionItem );
    end;
     
    destructor TMonComposant.Destroy;
    begin
      FreeAndNil( FCollection );
      inherited;
    end;
     
    procedure TMonComposant.SetCollection(const Value: TMaCollection);
    begin
      FCollection.Assign( Value );
    end;
     
    end.
    Alors voila en faisant comme ça la propriété Compo garde ses valeurs.

    Par contre j'ai rencontré un petit problème que j'ai tenté de résoudre à savoir lorsque Compo est assigné et que l'on veut changé le ItemType j'ai une violation d'accès qui apparaît mais qui n'empêche pas le fonctionnement une fois les erreurs passées.

    J'ai donc supposé que c'était le designer qui gueulait car cela ne se produit que lorsque l'objet est "déplié" dans l'inspecteur d'objet, s'il est replié par d'exception. Donc j'ai tenté de faire savoir au designer que j'étais en train de faire des modifs sur cette propriété et qu'il doit se mettre à jour en conséquence (ce sont les lignes de code entourés par des commentaires //designer) mais malheureusement je ne suis pas parvenu à régler ce problème.

    Je tourne sous D7 et j'aimerais savoir si tu as le même problème que moi ou pas ? S'il y a des experts du mode design qui peuvent répondre qu'il ne se gênent pas

  20. #20
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 152
    Points : 61
    Points
    61
    Par défaut
    Salut,

    je viens de tester ton code et je ne rencontre pas de soucis en mode design.
    Je peut modifier les valeurs de combo puis changer de type sans soucis.

    Par contre, j'ai rajouter un fonction virtuel et abstraite "operation" dans la classe TRootClass pour vérifier que mes valeurs sont bien conservé.

    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
      TRootClass = class( TPersistent )
      protected
       FOwner: TPersistent;
       function GetOwner: TPersistent; override;
      public
       Constructor Create( AOwner: TPersistent );
       procedure Operation;virtual;abstract;
      end;
     
      TClassA = class( TRootClass )
      private
        FAbcisse: Integer;
        FOrdonnee: Integer;
      public
        procedure Operation; override;
      published
       property Abcisse: Integer read FAbcisse write FAbcisse;
       property Ordonnee: Integer read FOrdonnee write FOrdonnee;
      end;
     
      TClassB = class( TRootClass )
      private
        FTexte: String;
      public
        procedure Operation; override;    
      published
       property Texte: String read FTexte write FTexte;
      end;
     
    { TClassA }
    procedure TClassA.Operation;
    begin
      showmessage( 'abscise : ' + inttostr(FAbcisse) + 'ordonné : ' + inttostr(FOrdonnee));
    end;
     
    { TClassB }
    procedure TClassB.Operation;
    begin
      showmessage('text : ' + FTexte);
    end;
    Le soucis c'est que je n'ai pas encore trouver comment on fait pour accéder a un item avec ton composant.
    Je suis surpris car lorsque je regarde ton diagramme des classes, je me rend compte que TMaCollectionItem n'est pas relier à TMonComposant.

    Merci pour le coup de main, je te dit des que j'en sais plus.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 10
    Dernier message: 16/08/2013, 21h03
  2. [Objet immuable] Comment faire ?
    Par smori dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 18/03/2013, 17h32
  3. Comment faire de la defensive copie avec un objet de type Collection
    Par l_informaticien dans le forum Collection et Stream
    Réponses: 12
    Dernier message: 20/01/2013, 21h56
  4. Réponses: 3
    Dernier message: 19/07/2007, 10h39
  5. comment faire pour imprimer à l'écran un objet
    Par GConstant dans le forum Général Python
    Réponses: 10
    Dernier message: 11/08/2004, 11h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo