![]() |
property setzen bzw. ändern
Hallochen, ich wieder!
Neues Problem: Unit2:
Delphi-Quellcode:
Und dazu aus Unit1, die von Unit2 die probperty PSheet ändern können soll:
unit devices;
interface uses kl2700,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, ComCtrls, StdCtrls, ExtCtrls; type TDevice1 = class(TForm) FPSheet: TTabSheet; procedure SetPSheet(var tst: TTabSheet); private public property PSheet: TTabSheet read FPSheet write SetPSheet; end; implementation var Dev1 : TDevice1; procedure TDevice1.SetPSheet(var tst: TTabSheet); begin Dev1.FPSheet:=tst; //hier ist dann vorbei - er wirft ne Fehlermeldung (Exception) end;
Delphi-Quellcode:
Nun stürtzt das Programm aber immer ab, wenn ich auf PSheet zugreifen will. Durch den Einzelschrittbetrieb kann ich sehen, daß es erst bei der direkten Zuweisung anhält.
var
Form1: TForm1; Dev1: TDevice1; procedure TForm1.cr_tabs; const TabTitles: array[0..4] of ShortString = ('Gerät1','Gerät2','Gerät3','Gerät4','Gerät5'); var i: integer; begin for i := 0 to (devcount-1) do with TTabSheet.Create(Self) do begin PageControl := Form1.PageControl1; Dev1.PSheet:=PageControl1.Pages[i]; //hier erfolgt der zugriff PageControl1.Pages[0].Show; end; end; Was kann falsch sein? -c- |
Re: property setzen bzw. ändern
Hi.
Du missbrauchst properties, die zum kapseln von lokalen objekt-feldern da sind, und nicht um an globalen rum zu manipulieren :wink: Teste es mal so:
Delphi-Quellcode:
procedure TDevice1.SetPSheet(var tst: TTabSheet);
begin self.FPSheet:=tst; //hier ist dann vorbei - er wirft ne Fehlermeldung (Exception) end; |
Re: property setzen bzw. ändern
Moin!
Das Self braucht nicht geschrieben werden in diesem Falle, ansonsten sind noch 2 Dinge auffällig: 1. Du hast in deinem Code in jeder der beiden Units die Variabel Dev1 : TDevice1 definiert - aber nun ist die Frage, wird überhaupt eine - und wenn, welche - mit einer Instanz von TDevice1 gefüllt? 2. Dein FPSheet ist schon Public definiert, somit frei von aussen zugreifbar - also, wozu die Properties? (siehe maximov). MfG Muetze1 |
Re: property setzen bzw. ändern
Momomomoment - nicht ganz so hastig! Wie gesagt, ich bin noch nicht lange dabei, Delphi zu programmieren. So die Standardsachen wie einfache Dateioperationen oder Statische Formulare usw. benötigen ja nicht so das Hintergrundwissen - die funktionieren halt einfach, wenn man sich da was zusammenklickt. Aber wenns dann um dynamische oder gar eben selbst erstellete Objekte geht, dann wirds schon schlimm - aber irgendwie muß man ja mal anfangen und daran kommen, nich?
So, und nun wieder zurück zum Thema! Wie meinste das genau mit instanziieren? Meinst Du, es müßte eine Instanz mittels Dev1.Create erzeugt werden? Nein, das kommt in beiden Units nicht vor. Bis jetzt kam ich aber an die anderen (hier zwar nicht zu sehen) Methoden heran, die noch damit verbunden sind. Und daß in beiden Units Dev1 defieniert wurde, dürfte doch auch nicht stören, da diese doch eigentlich nur für eine Unit als global zu sehen sind, oder? Und zum 2. Punkt: Ich wollte FPSheet ja auch schon direkt ansprechen, aber war das Programm auch der Meinung, daß das eine Zugriffsverletzung sei... Also weitersuchen und MEHR INPUT :shock: -c- PS: Wer kann ne gut Buchempfehlung aussprechen?! Aber nicht unbedingt so ein Buch, dass erst erklärt, was der Unterschied zwischen nem Interpreter und nem Kompiler ist. :stupid: |
Re: property setzen bzw. ändern
Moin!
Du hast in beiden Units
Code:
stehen. Dieses beides enthält nur einen Platzhalter wo du nachher eine Instanz von TDevice1 reinlegen kannst. Standardmässig gibt es sowas aber nicht in den Variablen, daher bekommst du bei dem Zugriff auf Dev1.xxx auch Probleme - da ist noch nix. Um da aber was reinzubekommen gibt es die Möglichkeit das Objekt anzulegen (instanziieren), und ja, es geht so wie du meintest (fast)
Var
Dev1 : TDevice1;
Code:
Die Frage ist dabei nur noch, welche Parameter du beim Create mit angeben musst, und in welchem Dev1 du das abspeicherst. Dadurch das du es in beiden Units deklaraiert hast, kann es leicht zu Verwechselungen kommen so dass du auf die falsche Variable zugreifst. Und du greifst ja auf Dev1 in deinem Code zu - und wenn da noch keine Instanz drinne ist in Dev1, dann kommt es zu der Zugriffsverletzung.
Dev1 := TDevice1.Create();
Ich bin noch nicht so lange hier (ein paar Tage), daher die Frage an die anderen: gibt es hier ein Tutorial für OOP ? MfG Muetze1 |
Re: property setzen bzw. ändern
Morgen Muetze!
Prinzipiell ist mir das mit OOP schon klar, schwer ist es eben, durch die ganzen Konventionen durchzublicken. Die Idee mit dem Tut und dann eben schön auf Delphi bezogen ist nicht schlecht, aber ich glaub, ich hab hier davon schon was gesehen. Aber bin auch noch nicht länger als Du dabei. Nochmal zurück zum Thema: warum kann ich aber dann trotzdem auf die Methoden aus TDevice1 zurückgreifen, auch wenns noch nicht instanziiert ist? -c- |
Re: property setzen bzw. ändern
Hi CBOB,
schau mal in deinen Project-Code. Offensichtlich hast du dein Formular aus Unit2 deinem Projekt hinzugefügt. Somit wird automatisch schon eine Instanz beim Prog-Start erzeugt. Nun kann ich natürlich nicht sagen, was du an dem vorliegenden Code alles geändert hast. Die übliche Vorgehensweise ist aber so: 1. Du fügst ein neues Formular in dein Projekt ein, und Delphi erzeugt automatisch den Aufruf
Delphi-Quellcode:
Somit besteht eine Instanze die genutzt werden kann. Üblicheweise erzeugt Delphi auch automatisch die Instanz-Variable im implementation-Teil deiner Formular-Unit (hier Unit2)
Application.CreateForm(TForm1, Device1);
2. Du machst das lieber alles alleine: hier wähle ich folgende Verfahrensweise. Zum Bsp. im Main-Form creiere ich das Formular im OnCreate Ereignes meines MainForm. Das dann, wenn es für die ganze Laufzeit erhalten bleiben soll. Dann muß aber beachtet werden, dass bei Aufrufen aus anderen Units die Instanz global verfügbar sein muß. Das hat oben Delphi aber automatisch für mich gemacht. Sinn bringt das eigentlich nur, für spezielle Nutzungen, bei denen Du das entsprechende Formular oder Objekt in einer Instanz unbedingt privat kapseln möchtest. Nun gut, was machst du im eigentlichen Object: Hier solltest du eigentlich nie globale Bezüge verwenden, da damit dein Object unflexibel wird. Es ist immer an speziell erstellte instanzen gebunden etc. In deinem eigenen Object kannst du der Einfachheit halber immer direkt auf eigene Eigenschaften und Methoden ohne Instanzangabe zugreifen. Der Parameter self wird sozusagen implizit unterstellt. Bsp.:
Delphi-Quellcode:
Deine Unit 2 sollte in der eigenen Erstellung eigentlich so aussehen:
procedure TDevice1.SetPSheet(var tst: TTabSheet);
begin FPSheet:=tst; end; // entspricht: procedure TDevice1.SetPSheet(var tst: TTabSheet); begin self.FPSheet:=tst; end;
Delphi-Quellcode:
Passiert das alles nicht per Drag and Drop im Fomular kümmerst Du dich selber um das Creieren Deiner Objekte.
unit devices;
interface uses kl2700,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, ComCtrls, StdCtrls, ExtCtrls; type TDevice1 = class(TForm) private FPSheet: TTabSheet; procedure SetPSheet(var tst: TTabSheet); public property PSheet: TTabSheet read FPSheet write SetPSheet; end; var Dev1 : TDevice1; implementation procedure TDevice1.SetPSheet(var tst: TTabSheet); begin FPSheet:=tst; //hier ist dann vorbei - er wirft ne Fehlermeldung (Exception) end; Machst du es per Drag and Drop, sind diese Public und ein Property tut wirklich nicht not. Gut, ich hoffe es war verständlich, Gruß oki |
Re: property setzen bzw. ändern
Zitat:
Und (besser man sagt es dir früher als spät) man sollte soweit wie möglich auf globale variablen verzichten, weil das schlechten stil fördert. |
Re: property setzen bzw. ändern
[quote="maximov"]
Zitat:
Gruß oki |
Re: property setzen bzw. ändern
@oki
Danke für die Ausführlichkeit! Hab das aber schon so irgendwie hingebogen bekommen - quasi übernacht :wink: . @max Aha, hab mir sowas in der Art schon gedacht. Was meinst Du hier aber genau mit Objectdaten? Und daß Globale Variablen vermieden werden sollten, war mir auch schon klar. Ich bemüh mich jedenfalls, wenig davon gebrauch zu machen. In einigen wenigen Fällen kommt man aber drum rum. Was ist eigentlich mit ner Buchempfehlung zum Thema? Woher habt Ihr Eure Erfahrung bzw. Wissen - zugeflogen kommt sowas bis jetzt ja noch nicht, oder? :angle: -c- |
Re: property setzen bzw. ändern
Moin!
Zitat:
Das geht nur mit statischen Funktionen (das ist der Name in C++, Delphi nennt das Class Procedure/Function). ---- Ich vermute immernoch, das du die ganze Zeit auf Dev1 aus der Unit zugegriffen hast, die Nil ist und in Unit2 wo die Instanz in der Dev1 vorhanden war auf die Methoden... MfG Muetze1 |
Re: property setzen bzw. ändern
@Muetze
Hab jetzt ordnungsgemäß in Unit1 eine Instanz von Dev1 erzeugt und in Unit2 die Definition von Dev1 entfernt. Und was soll ich sagen: Isch hoab doa uff'n Knobb gedrüggt und der gääht! :thuimb: Nächste kleine Frage am Rande: Wenn ich nun innerhalb von Unit2 eine ComboBox erzeugt hab und dann das OnChange Event auf eine weiter procedure 'CBChange' innerhalb von Unit2 gelenkt hab, kann ich doch nur von außen darauf zugreifen, wenn ich CBChange als public und als virtual definiere und dann innerhalb von Unit1 diese procedure dann überschreibe, oder? Zumindest wäre es ein Weg, weils halt funktioniert. Gäbe es aber auch andere Möglichkeiten? Und 2. Frage ist: Wenn ich nun die in Unit2 erzeugte ComboBox nehme und dann per Parent in das Form1 aus Unit1 hänge, wie kann ich dann auf das Ding ordnungsgemäß zugreifen? Ich habs mittels ewig langer Schlange:
Delphi-Quellcode:
rrealisiert, was mir aber nicht so gefällt, weil es dann ja immer an einer bestimmten Stelle in der Hirarchie erwartet wird. Und über einen Namen kann ich da ja auch nicht zugreifen, den weiß ja Form1 auch nicht.
with Form1.PageControl1.ActivePage.Controls[0] as TComboBox do
Uiih, doch wieder so lang geworden :oops: Gruß -c- |
Re: property setzen bzw. ändern
Zitat:
Delphi-Quellcode:
zB. unser schöne free würde sonst auch keinen sinn machen :wink:
type
TTest = class procedure NoStatic(str:string); end; { TTest } procedure TTest.NoStatic(str: string); begin ShowMessage(str); end; procedure TForm1.Button1Click(Sender: TObject); var x:TTest; begin x.NoStatic('No Exception'); end; |
Re: property setzen bzw. ändern
Moin!
maximov, du hast Recht. Ich habe beim vorherigen Post das nicht beachtet, das die VMT ja von der Klasse kommt und nicht bei der Instanz steht. Ich nehme alles zurück und behaupte das Gegenteil. MfG Muetze1 |
Re: property setzen bzw. ändern
Hey, und mit mir redet keiner mehr?
Nerv' ich mittlerweile schon so mit meinen Fragen? -c- |
Re: property setzen bzw. ändern
Das musste eben geklärt werden :wink:
Zitat:
Zitat:
|
Re: property setzen bzw. ändern
Moin!
Du? Ach du, ja, da war doch noch was... Zitat:
Zitat:
Bsp:
Delphi-Quellcode:
Und wo du das Create machst, dann sowas:
Type
TFormX = Class(TForm) dein vorhandener Form Code Private ComboBox_Neu : TComboBox; ...
Delphi-Quellcode:
Und im Code kannst du dann wie im letzten Teil geschrieben mit ComboBox_Neu. auf die Eigenschaften der ComboBox zugreifen. In den Events/Ereignissen die von der ComboBox ausgelöst werden, entspricht der Sender immer der ComboBox...
ComboBox_Neu := TComboBox.Create( ... wie gehabt ... );
ComboBox_Neu.Text := 'wasweissich'; MfG Muetze1 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz