Strona 1 z 1

Dynamiczny button->zdarzenie->problem

Nowy postNapisane: wtorek, 29 grudnia 2009, 23:02
przez markopol
Tworzę dynamicznie button.

w pliku Unit1.h mam

Kod: Zaznacz cały

__published:
private:
        TButton *Przycisk;
        void __fastcall funkcjaklik(TObject *Sender);

public:





W Unit1.cpp mam:

Kod: Zaznacz cały


void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Przycisk = new TButton(this);
   Przycisk->Parent = this;
   Przycisk->Left = 30;
   Przycisk->Top = 40;
   Przycisk->OnClick = funkcjaklik;
}

void __fastcall TForm1::funkcjaklik(TObject *Sender)
{

// tutaj nie wiem co wpisać

}








1. W jaki sposób zmieniać dowolną właściwość utworzonego dynamicznie buttona gdy kliknę na niego lewym przyciskiem myszy np. chce zmienić jego właściwość Caption

Pisząc w funkcjaklik:

Kod: Zaznacz cały
Caption="nowy";



Akcja wykonuje się na formie,a nie na utworzonym buttonie.

2. Załóżmy,ze na formie znajduje się 10 utworzonych dynamicznie buttonów,których własność Name to b1,b2.... itd. Chcę po kliknięciu na pierwszy z nich zmienić właściwość drugiego i trzeciego. Jak się odwołać do tych przycisków?


Męczę się z tym i już nie mam siły.

Proszę o pomoc.

Re: Dynamiczny button->zdarzenie->problem

Nowy postNapisane: środa, 30 grudnia 2009, 00:49
przez husky83
Program robi dokładnie to co mu karzesz..

Spróbuj raczej tak:
Kod: Zaznacz cały
Przycisk->Caption="nowy";

Pisząc po prostu Caption=... odwołujesz się do formy, a nie do przycisku...



Co do drugiego problemu, to robisz tak samo, tylko - deklarujesz sobie zdarzenie onclick, a potem
Kod: Zaznacz cały
void __fastcall nacisnieto_b1(TObject *Sender)
{
  b2->Caption="Przycisk2";
  b2->Top=30;
}

Re: Dynamiczny button->zdarzenie->problem

Nowy postNapisane: środa, 30 grudnia 2009, 09:58
przez Cyfrowy Baron
Kod: Zaznacz cały
void __fastcall TForm1::funkcjaklik(TObject *Sender)
{

// tutaj nie wiem co wpisać

}


Tutaj wpisujesz jakieś zadanie, które ma być wykonane po naciśnięciu tego dynamicznego przycisku Button, gdyż funkcja funkcjaklik po podłączeniu pod zdarzenie OnClick stała się jego zdarzeniem OnClick, np:

Kod: Zaznacz cały
void __fastcall TForm1::funkcjaklik(TObject *Sender)
{
ShowMessage("Kliknięto na przycisku Przycisk");
}


Definiując dynamiczny obiekt powinieneś jeszcze podać jego nazwę, by później można się do niego bez problemu odwoływać:

Kod: Zaznacz cały
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Przycisk = new TButton(this);
   Przycisk->Name = "Przycisk"; // <--
   Przycisk->Parent = this;
   Przycisk->Left = 30;
   Przycisk->Top = 40;
   Przycisk->OnClick = funkcjaklik;
}


Właściwość Caption obiektu Przycisk będzie taka sama jak jego nazwa (Name), tworząc obiekt możesz od razu zmienić mu właściwość Caption:

Kod: Zaznacz cały
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Przycisk = new TButton(this);
   Przycisk->Name = "Przycisk";
   Przycisk->Caption = "nowa nazwa"// <--
   Przycisk->Parent = this;
   Przycisk->Left = 30;
   Przycisk->Top = 40;
   Przycisk->OnClick = funkcjaklik;
}


Zmiana właściwości Caption nie zmienia jego właściwości Name, nie są one połączone. Przepisanie właściwości Name do Caption ma miejsce tylko wtedy gdy właściwość Name obiektu jest ustalana po raz pierwszy.
Chcąc zmieniać jakieś właściwości obiektów musisz je prawidłowo adresować, czyli musisz podać nazwę tegoż obiektu (Name). To że wpisujesz w zdarzeniu OnClick obiektu Przycisk: Caption = "jakaś nazwa"; nie oznacza, że odwołujesz się do obiektu w którego zdarzeniu to zostało napisane. To nie miałoby sensu. Zdarzenie jest podłączone z konkretnym obiektem, ale np. dzięki polimorfizmowi, mogą z niego korzystać również inne obiekty, więc nie sugeruj się przynależnością funkcji (zdarzenie to też funkcja) do obiektu.
Jeżeli nie podasz nazwy obiektu przed właściwością to kompilator potraktuje tą właściwość jako przynależącą do formularza, o ile formularz posiada taka właściwość, jeżeli jej nie posiada to kompilator zgłosi błąd.

Chcę po kliknięciu na pierwszy z nich zmienić właściwość drugiego i trzeciego.


By zmienić właściwości jakiegoś obiektu, taki obiekt musi być zdefiniowany i dla każdego z tych obiektów musisz stworzyć zdarzenie OnClick, czyli funkcji podpinanych pod to zdarzenie musi być tyle co obiektów, np: funkcja1klik, funkja2klik, funkcja3klik, itd... Można by się ewentualnie posłużyć polimorfizmem i tylko jedną funkcją-zdarzeniem, ale w przypadku gdy zmiana ma dotyczyć nie tego samego obiektu, lecz jego "sąsiada", to sprawa staje się nieco skomplikowana. Jeżeli jednak chcesz spróbować to o polimorfizmie przeczytasz w serwisie Cyfrowy Baron w dziale: teoria -> Rzutowanie typów, przypisanie polimorficzne.

Co się jednak nie tyczy polimorfizmu, lecz tego co napisałem wcześniej, to powinno to wyglądać mniej więcej tak:

Kod: Zaznacz cały
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   B1 = new TButton(this);
   B1->Name = "B1";
   B1->Caption = "Przycisk 1";
   B1->Parent = this;
   B1->Left = 30;
   B1->Top = 40;
   B1->OnClick = funkcja1klik; // 1

   B2 = new TButton(this);
   B2->Name = "B2";
   B2->Parent = this;
   B2->Left = 30;
   B2->Top = 70;
   B2->OnClick = funkcja2klik; // 2

   B3 = new TButton(this);
   B3->Name = "B3";
   B3->Parent = this;
   B3->Left = 30;
   B3->Top = 100;
   B3->OnClick = funkcja3klik; // 3
}
//-------------------------------------------------------------------
void __fastcall TForm1::funkcja1klik(TObject *Sender) //1
{
B2->Caption = "Przycisk 2";
}
//-------------------------------------------------------------------
void __fastcall TForm1::funkcja2klik(TObject *Sender) //2
{
B3->Caption = "Przycisk 3";
}


Lepiej by było gdybyś funkcjom-zdarzeniom nadawał nazwy bardziej powiązane z nazwami obiektów, np: B1Click, B2Click, B3Click, itd...