Delphi Can
Dinamik butonlarda event tanımı - Baskı Önizleme

+- Delphi Can (https://www.delphican.com)
+-- Forum: Delphi (https://www.delphican.com/forumdisplay.php?fid=3)
+--- Forum: Genel Programlama (https://www.delphican.com/forumdisplay.php?fid=6)
+--- Konu Başlığı: Dinamik butonlarda event tanımı (/showthread.php?tid=8016)

Sayfalar: 1 2


Dinamik butonlarda event tanımı - mnk - 16-01-2025

Merhabalar,
En basit haliyle sorunumu anlatabilmek için şu kodu hazırladım.
  public
    { Public declarations }
 end;

var
 Form1: TForm1;
 Nossa: array[1..4] of TButton;
 say:integer;
implementation

{$R *.dfm}
procedure TForm1.TIKLA(Sender: TObject);
begin
  ShowMessage('Test OK for '+Nossa[say].Caption);
end;

procedure TForm1.FormCreate(Sender: TObject);
var DummyText:string;
begin
for say:= 1 to 4 do
 BEGIN
 Nossa[say]:= Tbutton.Create(nil);
 Nossa[say].Parent := self;
 Nossa[say].Caption:='cisss '+inttostr(say);
 Nossa[say].Name:='cisss_'+inttostr(say);
 Nossa[say].Top:=10*say*3;
 Nossa[say].Left:=10;
  DummyText:= IntToStr(say); Memo1.Lines.Add(DummyText);
 Nossa[say].onClick:= TIKLA;
 END;
end;

end.

Bu kodla oluşan her butonun tıklandığında kendi caption bilgisini mesaj olarak göstermesini istiyorum. Sınırlı bilgimle Delphi 7'de bir yol bulamadım. En basit nasıl yapılabilir? Bir sonraki aşamada buton tıklama event'inin içine parametre gönderilebilir mi?

Teşekkürler.


Dinamik butonlarda event tanımı - mrmarman - 16-01-2025


  ShowMessage('Test OK for '+TButton(sender).Caption); 


işinizi görür.

Buton adına koyduğunuz prefix "cisss_" temizleyip hangi butona eriştiğinizi tespit edebileceğiniz gibi bir referans property delphi tarafından sunulmuştur.

Her buttonun TAG property'sine sayısal referans verebilirsiniz ki bunu da global array olarak kullandığınız dizi eleman index nosu kullanmak isteyebilirsiniz .

örneğin button create tanımlamalarına aşağıdakini eklerseniz;

Nossa[say].Tag := say;


buton click olayında


  ShowMessage('Test OK for '+TButton(sender).Caption + ' with button index ' + TButton(sender).tag ); 


Parametre olarak sender:tbutton gibi yanına eklemeler yaparak zenginleştirilebilir ancak tbutton sınıfını override edip ilk TButton geçen ifadenin üzerinde Type tanımı girilerek yeni özel bir TButton türetip event property üretilmesi gerekir. Diğer yandan dilerseniz Tag değeri ile index olarak kullanmak yerine parametre değeri gönderir, parametresi referans olan işi yaptırabilirsiniz.


Dinamik butonlarda event tanımı - mnk - 16-01-2025

Muharrem hocam merhabalar,
Tam aradığım gibi bir çözüm önermişsiniz. Tag değerini butona yazdırırken string'e dönüştürdüm sadece. Onun dışında verdiğiniz kod direk ne yapacağımı anlatıyor. Çok teşekkürler.
Diğer açıklamalarınıza yönelik biraz okuma yapıp deneyeceğim.
Selamlar.


Dinamik butonlarda event tanımı - mcuyan - 16-01-2025

TAg Kısmını şu tür durumlar için kullanırız. MEsela bir hızlı satış ekranınız var.

Buton captionuna: Ürün adı, TAg'ına ise ürünid tutarız. butona tıkladığında ise ortak bi procedure gidip satış alanına sender butonun tagi ile işlem yaptırırız. Resmen hayat kurtarıyor Smile


Cvp: Dinamik butonlarda event tanımı - mnk - 17-01-2025

(16-01-2025, Saat: 22:09)mcuyan Adlı Kullanıcıdan Alıntı: TAg Kısmını şu tür durumlar için kullanırız. MEsela bir hızlı satış ekranınız var.

Buton captionuna: Ürün adı, TAg'ına ise ürünid tutarız. butona tıkladığında ise ortak bi procedure gidip satış alanına sender butonun tagi ile işlem yaptırırız. Resmen hayat kurtarıyor Smile

Bu, çok şeyi kolaylaştıran bir ipucuymuş. Biraz daha detay ne güzel olurdu!


Dinamik butonlarda event tanımı - mcuyan - 17-01-2025

Anlamadım?


Dinamik butonlarda event tanımı - mnk - 18-01-2025

Nossa[say]:= Tbutton.Create(nil);
Nossa[say].Parent := self;
Nossa[say].onClick:= TIKLA;

Muharrem Bey'den gelen çözümü farklı denemelerle sıfırdan form larda uygulayıp, "tamam artık asıl koda alayım" dedim. Üstteki parenting satırı "self" için undeclared identifier hatası verip kalıyor.

Şu şekle çevirirsem butonlar oluşuyor. Ama bu kez de TIKLA için prosedür tanımlarını girmeme rağmen undeclared identifier hatası geliyor.
Nossa[say]:= Tbutton.Create(Form1);
Nossa[say].Parent := Form1;
Nossa[say].onClick:= TIKLA;

İlerleyemiyorum. Çözüm önerilerinizi alabilir miyim?
Teşekkürler.


Dinamik butonlarda event tanımı - mrmarman - 19-01-2025

kodu procedure bazında yazarsanız daha kolay yardımcı oluruz.

Procedure TForm1.ButonEkle();
begin
 Nossa[say]:= Tbutton.Create(nil);
 Nossa[say].Parent := self;
 Nossa[say].onClick:= TIKLA;
end;

derseniz self burada gönderilen formu tform1'den referans alır. Tanımsız diyorsa tform1 bağlantısı vermemiş olmalısınız.

Sonra butona tıkladığınızda gönderi sahibi  (Sender:tobject) bu (tform1 referanslı tikla procedure) ile butonu bildirir.

Nil olarak create ettiğiniz için de form kapanırsa buton free olmaz onun ayrıca free etme işi size kalır. nil yerine de self derdeniz form referansıyla  kendi yağında kavrulur.

Farklı formlarda button oluşturmak ise maksat, o formu parametre olarak verip, self yerine o parametre atanmalı.


-- -Bilgisayar başına geçtim bir örnek hazırladım aşağıda incelemek isteyebilirsiniz. Forma bıraktığınız bir buttona her tıkladığınızda yeni buton alt alta türetilecek. Türetilen butona basılınca da kendi ID'sini beyan edecek.
 


var
  Nossa : array of TButton;

procedure TForm1.Tikla(Sender: TObject);
begin
  ShowMessage('Test OK for '+TButton(sender).Caption + ' with button index ' + IntToStr(TButton(sender).tag) );
end;

procedure TForm1.ButonEkle();
var
  say : Integer;
begin
  SetLength(Nossa, length(Nossa) + 1);

  say := high(Nossa);

  Nossa[say]  := Tbutton.Create(self);
  Nossa[say].Parent   := self;
  Nossa[say].onClick  := TIKLA;
  Nossa[say].Left     := 300;
  Nossa[say].Tag      := say;

  if length(Nossa) > 1
    then
      Nossa[say].Top := Nossa[say-1].Top + Nossa[say-1].Height + 4
    else
      Nossa[say].Top := 10;
end;


procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  ButonEkle;
end;




kljhmzghotorrzvhzl2q.gif


Cvp: Dinamik butonlarda event tanımı - mnk - 20-01-2025

Hocam elinize sağlık. Okur okumaz denedim. Sonuç ekran görünümü ekte. Derli toplu kod yazma konusunda da bir iki ipucu yakalamak iyi oldu. 

Bir ilave soru sorabilir miyim?

Prosedür girişi (veya başlığı mı demeli) parantezli olsa da olmasa da kod çalışıyor. Ben şu ana kadar bu tür prosedürleri parantezsiz yazdım.

procedure TForm1.ButonEkle; şeklinde yazmak yerine procedure TForm1.ButonEkle(); parantezlerini koymak nasıl bir fark yaratıyor?

Bazen yazdığım kodlarda program normal çalışıyor gibi görünürken pat diye bir hata verip çıkıveriyor. Acaba bu parantez konusu o hatalardan birinin nedeni olabilir mi diye soruyorum.


Dinamik butonlarda event tanımı - mrmarman - 20-01-2025

Parantezler, parametre ihtiyacı yoksa ve/veya varsayılan değer alan parametre olduğunda tercih kullanarak bilerek ve isteyerek parametre girmediğimizi beyan ettiğimiz hallerde kullanılan etkisiz elemandır.

Bu durumda olmazsa da olur, sadece etik duygularla yazma gereği duyuyorum. Unutulmuş gibi olmuyor da kasıt belirtmiş oluyorum.