kizermomo
Messages postés6Date d'inscriptionvendredi 27 octobre 2006StatutMembreDernière intervention26 juillet 2007
-
24 juil. 2007 à 10:41
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 2009
-
25 juil. 2007 à 10:47
Bonjour a tous, en espérant être assez clair et précis sur ma demande.
Voici mon problème:
je crée un application qui utilise une MDIForm et plusieurs MDIChildForm.
Mon appli doit créer plusieures fenêtres enfants identiques
(qui contiennent des TChart qui dessinent un graphique, un timer et autres).Jusque là pas
de problème.
Par contre à l'exécution, je peut ouvrir autant de fenêtres que je
le souhaite mais elles sont "reliées" (c'est le même graphique qui
apparait ans chaque fenêtre).
Mes questions:
Faut-il crée une fonction constructor particulière pour ma FormChild concernée?
Comment créer des fenêtre qui sont indépendantes les unes des autres?
J'ai l'impression qu'à l'heure actuelle certains des composants de ma form enfant ne ne sont pas crées séparémment.
Voici ma procédure pour créer ma Form enfant:
procedure TListForm.CreateMdiChild(const Name : string);
var
Child: TChargeForm;
begin
Child := TChargeForm.Create(Application);
Child.Caption := Name;
end;
Et voila mon contructeur de From
constructor TChargeForm.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
end;
Quelqu'un pourrait eclairé ma lanterne?? Malgrè des recherches je n'ai pas trouvé (ou mal cherché) de solution semblable au problème soulévé!! Merci d'avance!!
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 25 juil. 2007 à 10:47
re,
les MDI n'ont rien de très spécial. Ce sont des forms normal. Et ce sont des objects. Si tu comprend bien ces deux points, t'as les grandes lignes. Après les trucs spécial MDI, ça vient directement de windows.
--------
var
ChargeForm: TChargeForm; //inutile. efface cette ligne. (c'est utile pour les form qui sont instancié une seul fois. comme ça t'as déjà l'instance)
--------
c'est juste, il te faut des var LOCAL ou des champs. SInon, TOUS les enfants vont partager la même var et donc tu aurra des problème de "concurence" cad d'écriture "simultanée" depuis plusieurs forms.
tu peux aussi les déclarer en var local de ta procedure GetList.
------
ChartCharge.Series[I].Repaint; //generalement inutile. ev. remplace par un "chart.invalidate" à la fin de ta mise a jour.
-------
Series : array[0..40] of TLineSeries;
si tu utilise UNE var local (voir mon precedent post), tu peux te passer de ce tableau.
-------
bon code,
PS: renseigne toi sur: TObjectList; series.beginupdate ; setlenght (as-tu réelement besoin de 65000 valeurs?);
Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 24 juil. 2007 à 12:12
salut,
ta méthode est correct. (On pourrait l'amélioré et plein d'autre méthode exist avec quelques avantage que tu n'as pas (comme utiliser une function plustot qu'une procedure pour créer tes mdiChild)). Mais c'est juste.
ton problème vient surement de la manière dont tu crée ton TChart/series.
Pourrais-tu nous indiquer comment sont crée les chart/series? On design time(ie: Delphi)? Run time(ie: par code)?
Utilises-tu des var global dans ta form MdiChild? (tu ne devrait utiliser que des champs de l'object form)
bon code,
Loda
PS: c'est marrant, ça fait une année que je boss sur un prog MDI avec des TChart. :-D
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
kizermomo
Messages postés6Date d'inscriptionvendredi 27 octobre 2006StatutMembreDernière intervention26 juillet 2007 24 juil. 2007 à 12:27
Salut Loda,
merci de t'interesser à mon problème.
Ma Form enfant contient un TChart qui est déclaré comme suit:
type TChargeForm = class(TForm)
PnlActn: TPanel;
GrdPnlActn: TJvGradient;
MemReq: TMemo;
BtnLaunch: TJvXPButton;
EdInt: TSpinEdit;
Label1: TLabel;
ChartCharge: TChart;
Timer: TTimer;
Ensuite, pour initialiser mon Chart et les Séries, je le fais lors de la création de ma Form comme ceci:
procedure TChargeForm.FormCreate(Sender: TObject);
var
I : integer;
begin
If ListForm.ChbxMultiSel.Checked then begin
If ListForm.DBGridList.SelectedRows.Count>0 then begin
With ListForm.DBGridList.DataSource.DataSet do begin
For I:=0 to ListForm.DBGridList.SelCount-1 do begin
GotoBookMark(pointer(ListForm.DBGridList.SelectedRows.Items[I]));
Series[I] := TLineSeries.Create(Self);
Series[I].ParentChart := ChartCharge;
Series[I].Title := FieldByName('Lib').AsString;
TUrl[I] := MainForm.TblEtude.FieldByName('Url').AsString;
ChartCharge.Series[I].SeriesColor := MainForm.TblEtude.FieldByName('Clr').AsVariant;
end;//for
end;//with
end;//if
end//if
ListForm.Close;
end;
Pour Info ma variable Series est un array de TLineSeries (car nombre de courbe variable) déclarée après implementation.
Le tableau TUrl contient une adresse qui me permet d'aller faire une requête.
Mon appli doit dessiner un graphique en fonction du temps de réponse pour chaque requête effectuée.
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 24 juil. 2007 à 13:51
re,
"Pour Info ma variable Series est un array de TLineSeries (car nombre de courbe variable) déclarée après implementation." c'est ça. Comme il est déclarer dans l'unité au lieu de la class, c'est une var GLOBAL. donc tu la partage entre toute tes forms.
essai un truc genre (pas testé):
procedure TChargeForm.FormCreate(Sender: TObject);
var
I : integer;
aSeries: TLineSeries; begin
If ListForm.ChbxMultiSel.Checked then begin
If ListForm.DBGridList.SelectedRows.Count>0 then begin
With ListForm.DBGridList.DataSource.DataSet do begin
For I:= 0 to ListForm.DBGridList.SelCount-1 do begin
GotoBookMark(pointer(ListForm.DBGridList.SelectedRows.Items[I]));
aSeries := TLineSeries.Create(Self);
aSeries.ParentChart : = ChartCharge; // add la serie au chart ; tu peux aussi faire ChartCharge.AddSeries(ASeries). c'est la meme choses aSeries.Title := FieldByName('Lib').AsString;
TUrl[I] := MainForm.TblEtude.FieldByName('Url').AsString;
aSeries.SeriesColor := MainForm.TblE
<hr size="2" width="100%" />
renseigne toi sur la portée/visibilité des variable/champs. Ev. fait quelques test dans une form simple.
un champs d'object est une part de l'object (et donc unique par object). Une espace mémoire est alloué pour chaque champs de chaque object.
une var dans une unité (après ou avant implementation avec le mot VAR) est global (public ou privé). et donc n'existe qu'UNE fois.
fait aussi bien la différence entre "self" et "form1". self refer l'object (instance). alors que Form1 est UN (parmis d'autre) object de type Tform1. dans les methode de class, utilise toujours self (et non la var global form1)
bon code,
Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Vous n’avez pas trouvé la réponse que vous recherchez ?
kizermomo
Messages postés6Date d'inscriptionvendredi 27 octobre 2006StatutMembreDernière intervention26 juillet 2007 24 juil. 2007 à 17:31
J'ai testé avec la modification mais rien n'y fait.
Par contre j'ai aussi un TTimer, un TDataSource et un composant fait maison qui me permet de faire ma requête.
Faut'il que je crée ces composants spécifiquement lors de la création de mes fiches enfants???
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 25 juil. 2007 à 09:19
re,
c'est vrai que la modif que je t'ai indiqué n'explique pas ton problème de "lien".
dit moi, comment remplit tu les séries? Utilise tu des var global pour fournir les données? Il y a forcement un moment ou tu reutilise un pointeur ou une var global pour chaque form. Et ton timer? c'est pour un refresh? stp copie le code pour voir. utilises-tu "DBGridList.SelectedRows" dans tes calculs? ou une autre partie de ton DBGridList?
peux-tu me précisier ce qui est la même choses entre tes form? les données du chart (je suppose)? Arrive tu a voir quel données sont affichée? Les première? les dernières? la selection de la grille?
"Faut'il que je crée ces composants spécifiquement lors de la création de mes fiches enfants???"
tout ce qui doit être unique par enfant doit être crée dans le formcreate ou le create. Note que la pluspart des create sont appelé automatiquement. Si ce n'est pas clair ce qui doit être crée où, dit moi.
Le ttimer par exemple: Si tu le "pose" sur la fiche(comme pour un boutton), tu n'as pas besoin de le crée à la main.
pour le timer, si c'est pour faire un refresh tu peux en avoir qu'un pour toute les form, mais il faut qu'il appel une methode "Monrefresh" pour chaque form.
A+
Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
kizermomo
Messages postés6Date d'inscriptionvendredi 27 octobre 2006StatutMembreDernière intervention26 juillet 2007 25 juil. 2007 à 09:52
Tout d'abord, encore merci pour tes précisions. J'apprécie qu'on prenne le temps de m'explique. Je n'aime pas utiliser des méthodes sans les comprendre et comme les MDI sont nouvelles pour moi je voudrait "maitriser" le sujet.
Voila ce que je déclare dans mon type TForm:
type
TChargeForm = class(TForm)
PnlActn: TPanel;
GrdPnlActn: TJvGradient;
MemReq: TMemo;
BtnLaunch: TJvXPButton;
EdInt: TSpinEdit;
Label1: TLabel;
ChartCharge: TChart;
Timer: TTimer;
TableOffre: TXMLCDS; //composant maison
DtSrc: TDataSource;
TableOffreI0: TIntegerField;
TableOffreS1: TStringField;
TableOffreS2: TStringField;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure BtnLaunchClick(Sender: TObject);
procedure TimerTimer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
constructor Create(AOwner : TComponent); override;
procedure GetList;
end;
var
ChargeForm: TChargeForm;
implementation
uses UnitList, UnitMain;
var
Col : integer =0;
K : integer = 0;
MyVal : array[0..65000,0..40] of integer; // tableau on je stocke les valeurs des séries à insérer dans mon graphique
TTime : array[0..65000] of string; //tableau dans lequel je stocke l'heure ou les requêtes sont effectuées
TUrl : array[0..40] of string;
TClr : array[0..40] of TColor;
// le problème vient-il du fait que je déclare mes variables ici
{$R *.dfm}
Pour ce qui est de mon Timer, il me sert à gérer l'interval où les requêtes ont lieu (donc pas le même sur chaque fiche enfant).
Je fais un refresh de mon Chart à la fin de ma requête une fois que j'ai insérer ma valeur dans le tableau et mis la série concernée à jour (plusieures séries quand plusieures courbes):
//procédure pour click sur bouton de lancement des requêtes
procedure TChargeForm.BtnLaunchClick(Sender: TObject);
begin
Timer.Interval := (EdInt.Value*1000);
EdInt.Enabled := False;
FillChar(MyVal,SizeOf(MyVal),0);
FillChar(TTime,SizeOf(TTime),0);
Col := 0;
ChartCharge.MaxPointsPerPage := Trunc(21600/EdInt.Value);
Timer.Enabled := True;
end;
//procédure lors de l'activation du timer
procedure TChargeForm.TimerTimer(Sender: TObject);
begin
GetList;
end;
Pour mettre a jour mes séries, je le fait dand a procédure GetList:
procedure TChargeForm.GetList;
var
Result : boolean;
I,J : integer;
T1,T2,T3 : real;
D : TDateTime;
begin
T1 := Time;
D := Date;
For I:=0 to ChartCharge.SeriesCount-1 do begin
With TableOffre do begin
If Active then Close;
T2 := Time;
Url := TUrl[I];
end;//with //avec mon with, j'envoi ma requête
T3 := Time;
MyVal[Col,I] := MilliSecondsBetween(T2,T3); //je calcul le temp mis pour effectuer ma requete
ChartCharge.Series[I].Clear;
If Col>ChartCharge.MaxPointsPerPage then
K:=K+1;
For J:=K to Col do
ChartCharge.Series[I].Add(MyVal[J,I],TTime[J],TClr[I]); //Je met ma série à jour
If MyVal[Col,I]>ChartCharge.LeftAxis.Maximum then
ChartCharge.LeftAxis.Maximum := MyVal[Col,I];
ChartCharge.Series[I].Repaint;
end;//for
MemReq.Lines.Add(DateTostr(Date)+' '+TimeToStr(T1)+': Requêtes effectuées');
TTime[Col]:= TimeToStr(T1);
Col := Col+1;
end;
Autrement voici aussi le code de ma procédure Create de la form (où je crée les séries nécessaires):
procedure TChargeForm.FormCreate(Sender: TObject);
var
I : integer;
Series : array[0..40] of TLineSeries;
begin
Col := 0;
If ListForm.ChbxMultiSel.Checked then begin
If ListForm.DBGridList.SelectedRows.Count>0 then begin
With ListForm.DBGridList.DataSource.DataSet do begin
For I:=0 to ListForm.DBGridList.SelCount-1 do begin
GotoBookMark(pointer(ListForm.DBGridList.SelectedRows.Items[I]));
Series[I] := TLineSeries.Create(Self);
Series[I].ParentChart := ChartCharge;
Series[I].Title := FieldByName('Lib').AsString;
TClr[I] := MainForm.TblEtude.FieldByName('Clr').AsVariant;
TUrl[I] := MainForm.TblEtude.FieldByName('Url').AsString;
ChartCharge.Series[I].SeriesColor := TClr[I];
end;//for
end;//with
end;//if
end//if
end;
A la lecture de ta réponse précedente, je pense que mes variable tableau et autres ne sont surement pas déclarées au bon endroit.
Est-ce bien ca ou je n'en ai pas fini avec ce souci!?!