![]() |
TImages verwalten
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich habe ein Programm zum Scannen. Dieses legt die Bilder zunächst nacheinander in einer
Delphi-Quellcode:
ab und speichert die dann als png-Dateien.
TImageList
Jetzt möchte ich das Programm gern erweitern. Dazu sollen die Bilder statt in einer TImageList jeweils erst als
Delphi-Quellcode:
nebst 3
TImage
Delphi-Quellcode:
in einer
TRadioButtons
Delphi-Quellcode:
untereinander angezeigt werden. Hintergrund ist der, dass die Bilder standardmäßig in schwarzweiß eingescannt werden. Allerdings soll/muss es hin und wieder auch mal Fotos geben. Auch diesen Fall löst mein Programm im Ansatz. Allerdings gibt es immer wieder Nutzer, die einfachen Text mit 16 Mio. Farben einscannen und damit sinnloser Weise riesige Dateien erzeugen. Die Bilder sollen daher selbst beim Einscannen in Farbe nachträglich umgewandelt werden können - dafür die TRadioButtons.
TScrollBox
Ein Screenshot, wie ich es gern hätte, ist angehängt. Wie man TImage und TRadioButton zur Laufzeit erzeugt, ist klar. Klar ist mehr oder weniger auch die Umwandlung. Es geht also wirklich nur um das Vorhalten/Anzeigen für den Benutzer zur Laufzeit. Meine Überlegung geht jetzt dahin, Image und Buttons in ein Object zu packen und dann das ganze in einer Liste abgeleitet von
Delphi-Quellcode:
zu organisieren. In dieser kann man mit
TStringList
Delphi-Quellcode:
derartiges erledigen.
AddObject();
Wäre das völlig abwegig? Falls ja, wie macht man es richtig[tm]? Ich lese gern selbst. Im Moment fehlen mir aber die passenden Suchworte für mein Problem. Daher bitte nicht gleich meckern, falls das Problem schon einmal ausführlich behandelt wurde, sondern lieber eine Links setzen. Danke. Gruß, Alex |
AW: TImages verwalten
Zunächst würde ich die Bilder nicht komplett im Speicher behalten sondern jeden Scan direkt auf die Platte schreiben und merken (in einer Liste).
Für eine Komponenten-Komposition (TImage, TRadioButtons) eignen sich Frames sehr schön. Einfach ein Frame bauen und dann für jeden Scan eine Instanz erzeugen und in die Scrollbox packen. Die Bilder werden für die Ansicht ja nicht in der vollen Auflösung benötigt, somit wäre es auch ratsam die Bilder selber nur in einer reduzierten Auflösung für die Anzeige bereitzustellen. Mit einer PaintBox könnte man auch auf gecachte Bilder zurückgreifen, die im Hintergrund geladen werden. Auch das Umrechnen der Bilder sollte in einem Thread erfolgen, somit musst du eh mit Threads hantieren ;) |
AW: TImages verwalten
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für die Antwort.
Zitat:
Zitat:
Zitat:
Zum zweiten - das kommt noch :-D Und nun zu meiner Lösung: Ich hatte bei der Suche nach Frames im Netz die Möglichkeit entdeckt, Formulare anzudocken. Das klappt prima in einer
Delphi-Quellcode:
. Und der Vorteil (mit Frames kenne ich mich nicht aus) ist der, dass ich die Formulare schon zu Entwurfszeit basteln kann. Ich habe jetzt bloß noch ein Problem:
TPageControl
Wie schaffe ich es in der TPageControl auf das Schließen eines Fensters zu reagieren, so dass ich den TabSheet ebenfalls schließen kann? Ich habe meinen Code mal angehängt. Wenn dazu jemand eine Lösung hätte, wäre mein Problem - wenn auch anders als in der Überschrift evtl. gedacht - gelöst. Gruß und danke für den Push in diese Richtung! Alex |
AW: TImages verwalten
Die Anwendung wird nicht aufgehalten, wenn die Aktionen in einem Thread erfolgen (speichern, laden, umrechnen) ;)
Zum Schließen des Tabs musst du eigentlich rein gar nichts machen ... ok bis auf eins:
Delphi-Quellcode:
Wenn du jetzt das Formular schließt, dann wird es durch das Setzen von
type
TDockForm = clas( TForm ) protected // Ich könnte auch den Event OnClose nehmen, da ich aber von dieser Form // weitere ableiten möchte, ist dieser Weg etwas robuster :o) procedure DoClose( var Action: TCloseAction ); override; end; TDockFormClass = class of TDockForm; procedure TDockForm.DoClose( var Action: TCloseAction ); begin Action := caFree; inherited; // <- dort wird der Event OnClose gefeuert end;
Delphi-Quellcode:
auch automatisch zerstört, was wiederum automatisch den Tab aus dem PageControl entfernt :)
Action := caFree
Vorausgesetzt, die Form wird auch so dort eingedockt:
Delphi-Quellcode:
Wenn du diese
procedure TMyForm.DockNewForm( APageControl : TPageControl; ADockFormClass : TDockFormClass );
var LForm : TDockForm; begin LForm := TDockFormClass.Create( APageControl ); try LForm.ManualDock( APgeControl, nil, alClient ); LForm.Visible := True; LForm := nil; finally LForm.Free; end; end;
Delphi-Quellcode:
als Basis für deine weiteren DockFOrms nimmst, dann kannst du nach Belieben dort die unterschiedlichsten DockForms an dein PageControl hängen und diese werden dann beim Schließen automatisch aufgeräumt und der Tab geschlossen :)
TDockForm
|
AW: TImages verwalten
Zitat:
Ich kann aber nirgends ein Ereignis wie
Delphi-Quellcode:
finden. Und dann habe ich noch das Problem wo bzw. wie ist
onDockNewForm
Delphi-Quellcode:
definiert?
TDockFormClass
[edit] Und noch ein Problem fällt mir ein: Wie greife ich auf die einzelnen Komponenten (TImage etc.) nach dem Erstellen des angedockten Forms zu? Der Benutzer soll die Bilder erst scannen. Dann mit dem Button Bilder, die er nicht haben will, löschen können und schließlich über einen zentralen Save-Button alle Bilder nacheinander abspeichern. Letzteres soll dann über einen Thread vom Hauptformular erfolgen. Ich muss also irgendwie rankommen... [/edit] Gruß, Alex |
AW: TImages verwalten
Zitat:
Delphi-Quellcode:
procedure TMyForm.DockNewForm( APageControl : TPageControl; ADockFormClass : TDockFormClass ) : TDockForm;
var LForm : TDockForm; begin LForm := TDockFormClass.Create( APageControl ); try LForm.ManualDock( APgeControl, nil, alClient ); LForm.Visible := True; Result := LForm; LForm := nil; finally LForm.Free; end; end; Zitat:
Delphi-Quellcode:
type
TDockForm = class( TForm ) protected // Ich könnte auch den Event OnClose nehmen, da ich aber von dieser Form // weitere ableiten möchte, ist dieser Weg etwas robuster :o) procedure DoClose( var Action: TCloseAction ); override; end; TDockFormClass = class of TDockForm; // <--- DA Zitat:
Delphi-Quellcode:
drin ist? Das wird für die Anzeige benötigt ... aus und Ende.
TImage
Erstelle dir ein Daten-Objekt, was alle Informationen beinhaltet und merke dir dort alle Informationen zu jedem gescannten Bild und organisiere diese in einer Liste. Zu jedem Daten-Objekt gibt es dann eine Form (der du das zugehörige Daten-Objekt an die Hand gibts), die die Inhalte aus dem Daten-Objekt anzeigen und auch die Eingaben des Benutzers dort ablegen kann. Wenn der Benutzer fertig ist, dann gehts du einfach durch deine Liste und arbeitest die einzelnen Bilder ab. Die einzelnen Forms interessieren nicht mehr ;) |
AW: TImages verwalten
Danke für die Erläuterungen.
Zitat:
Aber müsste es nicht richtiger Weise dann
Delphi-Quellcode:
statt
function
Delphi-Quellcode:
heißen?
procedure
Und wo genau wird die Instanz übergeben (Result:=... oder Var in der Definition der Procedure)? Zitat:
Zitat:
|
AW: TImages verwalten
Zitat:
Zitat:
|
AW: TImages verwalten
Zitat:
Delphi-Quellcode:
die Instanz freigegeben.
finally
Das ist eigentlich eine sehr übliche und sinnvolle Vorgehensweise wenn man nicht auf Speicherlecks steht.
Delphi-Quellcode:
Auch wenn es sich im Beispiel um eine Komponente mit Owner handelt, was für eine korrekte Freigabe durch den Owner sorgt. Eine ungenutzte Instanz im Speicher ist zuviel und solche Fehler (Speicher läuft im Betrieb voll) sind nachher nur schwer zu finden, denn beim Beenden gibt es kein Speicherleck, dafür ist irgendwann der Speicher voll und die Anwendung verabschiedet sich.
function FooFactory : TFoo;
var LFoo : TFoo; begin LFoo := TFoo.Create; try ... Result := Lfoo; LFoo := nil; // auf nil setzen finally // bei einer Exception wird die Instanz freigegeben, // sonst nicht, denn dann zeigt LFoo ja auf nil ;o) LFoo.Free; end; end; |
AW: TImages verwalten
Danke. Es wird langsam klarer und zeigt sich, dass es für Gelegenheitprogrammierer wie mich schwer werden dürfte. Ich habe jetzt folgendes zusammengebastelt. Allerdings weiß ich nicht, wie ich herausbekomme, ob der Benutzer ein Form selbst mit Close "zerstört" hat:
Delphi-Quellcode:
[edit]
Type
TMainForm = Class(TForm) BtnAdd : TButton; BtnInfo : TButton; PCPics : TPageControl; Procedure FormCreate(Sender: TObject); Procedure BtnAddClick(Sender: TObject); Procedure BtnInfoClick(Sender: TObject); Procedure FormDestroy(Sender: TObject); Protected fCount : Integer; fPicList : TList; End; Var MainForm : TMainForm; Implementation {$R *.dfm} Procedure TMainForm.FormCreate(Sender: TObject); Begin fCount:=0; fPicList:=TList.Create; End; Procedure TMainForm.BtnAddClick(Sender: TObject); Var aPNG : TPngImage; lForm : TDockForm; Begin aPNG:=TPngImage.Create; Try aPNG.LoadFromFile('.TestBilder\_0001.png'); aPNG.RemoveTransparency; lForm:=TDockFormClass.Create(PCPics); Try lForm.ManualDock(PCPics, nil, alClient); lForm.Visible:=True; LForm.IMGScan.Picture.Bitmap.Assign(aPNG); Inc(fCount); lForm.Caption:='Bild ' + FormatFloat('0,', fCount); fPicList.Add(lForm); // <- in Liste merken lForm:=nil; // 1:1 übernommen Finally lForm.Free; // 1:1 übernommen PCPics.ActivePageIndex:=Pred(PCPics.PageCount); End; Finally aPNG.Free; End; End; Procedure TMainForm.BtnInfoClick(Sender: TObject); Var I : Integer; lDockForm : TDockForm; Begin If (fPicList.Count = 0) Then Exit; I:=PCPics.ActivePageIndex; lDockForm:=fPicList.Items[I];// <- so greife ich jetzt zu. With lDockForm Do Try ShowMessage('Original' + #09 + BoolToStr(RBorgjpg.Checked, True)); Finally End; End; Procedure TMainForm.FormDestroy(Sender: TObject); Begin Try While (fPicList.Count > 0) Do fPicList.Delete(0); Finally fPicList.Free; End; End; End. Also der Zugriff klappt. Bleibt die Frage, wie ich herausbekomme, ob der Benutzer eine Form gelöscht hat... [/edit] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:32 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