CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Parę problemów

Parę problemów

dział ogólny

Parę problemów

Nowy postprzez Dunay » środa, 18 kwietnia 2012, 20:40

Witam,
Na zaliczenie muszę zrobić mały projekcik w C++ Builder 6. Większość to działania obiektowe. A teraz do rzeczy. Projekt zakłada utworzenie testu. Chciałbym aby po wciśnięciu przycisku uruchamiał się licznik odmierzający czas do zakończenia testu. Kombinowałem z obiektem Timer ale na razie udało się tylko ustawić, że po zakończeniu odliczania formularz testu jest ukrywany i pojawia się drugi podsumowujący. W drugim formularzu daję przycisk a pod nim Close(). I tu kolejny problem, po kliknięciu przycisku zamyka się formularz drugi, ale w pierwszym nadal odlicza Timer, a chciałbym żeby całkiem zamknąć program.
Avatar użytkownika
Dunay
Bladawiec
Bladawiec
 
Posty: 15
Dołączył(a): środa, 18 kwietnia 2012, 16:28
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Professional x86
Kompilator: C++ Builder 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Parę problemów

Nowy postprzez Cyfrowy Baron » środa, 18 kwietnia 2012, 22:54

Timer włączasz i zatrzymujesz przypisując właściwości Enabled wartość true (włącz) lub false (wyłącz):

KOD cpp:     UKRYJ  
Timer1->Enabled = false; // zatrzymanie zegara


Funkcja Close() zamyka całą aplikację, ale tylko wtedy, gdy zostanie wywołana z głównego formularza aplikacji, gdyż zamknięcie głównego formularza jest równoznaczne z zamknięciem aplikacji. Jeżeli chcesz zamknąć aplikację z dowolnego formularza użyj kodu:

KOD cpp:     UKRYJ  
Application->Terminate();

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Dunay
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Parę problemów

Nowy postprzez Dunay » sobota, 21 kwietnia 2012, 09:38

Działa świetnie. Chciałbym teraz zrobić coś takiego że jak pozostanie np. 5 minut do końca to pokaże się komunikat "Pozostało Ci 5 minut"
czyli np.
Kod: Zaznacz cały
if (Timer1->Interval=5000)
ShowMessage("Pozostało Ci 5 minut");
Avatar użytkownika
Dunay
Bladawiec
Bladawiec
 
Posty: 15
Dołączył(a): środa, 18 kwietnia 2012, 16:28
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Professional x86
Kompilator: C++ Builder 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Parę problemów

Nowy postprzez Cyfrowy Baron » sobota, 21 kwietnia 2012, 09:43

Gdzie i w jakiej formie masz zapisany/ustalony maksymalny czas testu?



Właściwość Interval odpowiada za częstotliwość z jaką tyka zegar, a 5000 oznacza, że tyka co 5 sekund. Zegar TTimer nie przechowuje czasu w żadnej formie, tylko sobie tyla z zadaną częstotliwością.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Parę problemów

Nowy postprzez Dunay » sobota, 21 kwietnia 2012, 10:15

Kod: Zaznacz cały
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
Timer1->Interval=10000;
}


Nie patrz na wartości bo są tymczasowe/testowe ;)
Avatar użytkownika
Dunay
Bladawiec
Bladawiec
 
Posty: 15
Dołączył(a): środa, 18 kwietnia 2012, 16:28
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Professional x86
Kompilator: C++ Builder 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Parę problemów

Nowy postprzez Cyfrowy Baron » sobota, 21 kwietnia 2012, 11:43

Dunay napisał(a):
KOD cpp:     UKRYJ  
Timer1->Interval=10000;


Przecież wyraźnie napisałem:
Cyfrowy Baron napisał(a):Właściwość Interval odpowiada za częstotliwość z jaką tyka zegar, a 5000 oznacza, że tyka co 5 sekund. Zegar TTimer nie przechowuje czasu w żadnej formie, tylko sobie tyla z zadaną częstotliwością.




Masz tutaj przykład takiego odliczającego zegara do przodu i od końca:

KOD cpp:     UKRYJ  
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"

 /* Włączam bibliotekę mmsystem.hpp do projektu - wymagana dla funkcji timeGetTime() */
#include <mmsystem.hpp>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

long StartTime = 0, ElapsedTime = 0, Minutes = 0;
int MaxTime = 60; /* maksymalny czas testu w minutach - 60 minut */
int TimeLeft = 5; /* wartość dla pierwszego komunikatu przed końcem testu */
BOOL LockTimeLeft = false;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{ /* Konstruktor klasy formualrza */
  Timer1->Interval = 500; /* ustawiłem tykanie co pół sekundy */
   Label1->Caption = "0:00";
   Label2->Caption = "60:00";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonStartClick(TObject *Sender)
{  /* Zdarzenie OnClick przycisku ButtonStart typu TButton */
 if( Timer1->Enabled )
 {
   Timer1->Enabled = false;
   ButtonStart->Caption = "Start";

   Label1->Caption = "0:00";
   Label2->Caption = "60:00";
 }
 else
 {
   StartTime   = timeGetTime();
   ElapsedTime = 0;
   Minutes = 0;
   LockTimeLeft = true;

   Timer1->Enabled = true;
   ButtonStart->Caption = "Stop";
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{ /* Zdarzenie OnTimer obiektu Timer1 typu TTimer */
 int Seconds, EndMinutes, EndSeconds;

 ElapsedTime = timeGetTime() - StartTime;

 Seconds = ((int)ElapsedTime ) / 1000;

 if(Seconds == 60)
 {
  Minutes++;
  Seconds = 0;
  StartTime = timeGetTime();
 }

 EndMinutes = MaxTime - Minutes - 1;
 EndSeconds = 59 - Seconds;

 Label1->Caption = (String)Minutes +  FormatCurr( ":0#", Seconds ); /* Czas upływajacy */
 Label2->Caption = (String)EndMinutes +  FormatCurr( ":0#", EndSeconds ); /* Czas pozostały do końca */

 if( EndMinutes == TimeLeft && LockTimeLeft )
 {
  LockTimeLeft = false;
  ShowMessage("Do końca testu pozostało 5 minut");
 }

 if(EndMinutes <= 0 && EndSeconds <= 0)
 {
  ButtonStartClick(Sender); /* zatrzymanie testu i zegara */

  ShowMessage("KONIEC TESTU");
 }
}
Ostatnio edytowano sobota, 21 kwietnia 2012, 11:49 przez Cyfrowy Baron, łącznie edytowano 1 raz
Powód: Naniosłem poprawki.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Dunay
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Parę problemów

Nowy postprzez Dunay » poniedziałek, 23 kwietnia 2012, 12:39

Proste pytanie. Jak pobrać zmienną z Form1 do Form2?
Avatar użytkownika
Dunay
Bladawiec
Bladawiec
 
Posty: 15
Dołączył(a): środa, 18 kwietnia 2012, 16:28
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Professional x86
Kompilator: C++ Builder 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Parę problemów

Nowy postprzez Cyfrowy Baron » poniedziałek, 23 kwietnia 2012, 16:33

Patrz: serwis Cyfrowy Baron dział: Teoria -> Przekazywanie obiektów i funkcji pomiędzy formularzami.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Parę problemów

Nowy postprzez Dunay » poniedziałek, 23 kwietnia 2012, 17:05

Właśnie przeglądałem ten dział. Ale wraz coś jest nie tak. Otóż, zgodnie z Twoimi słowami deklaruję w Unit1.h zmienną publiczną
KOD cpp:     UKRYJ  
String wynik;

następnie pod przyciskiem daję:
KOD cpp:     UKRYJ  
wynik="Próba";
Form1->Visible=false;
Form2->Visible=true;


Natomiast Unit2.cpp wygląda następująco
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
Application->Terminate();
}
//---------------------------------------------------------------------------

void __fastcall TForm2::FormCreate(TObject *Sender)
{
Edit1->Text=Form1->wynik;
}


Kompilacja przebiega bezproblemowo ale w Edit1 w Form2 nie pojawia się napis "Próba"
Avatar użytkownika
Dunay
Bladawiec
Bladawiec
 
Posty: 15
Dołączył(a): środa, 18 kwietnia 2012, 16:28
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Professional x86
Kompilator: C++ Builder 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Parę problemów

Nowy postprzez polymorphism » poniedziałek, 23 kwietnia 2012, 17:38

Nie pojawia się, ponieważ nie tak definiuje się zmienne globalne. Tak ma być:

Unit1.h:
KOD cpp:     UKRYJ  
extern String wynik;

Unit1.cpp:
KOD cpp:     UKRYJ  
String wynik;
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Parę problemów

Nowy postprzez Cyfrowy Baron » poniedziałek, 23 kwietnia 2012, 19:27

polymorphism napisał(a):Nie pojawia się, ponieważ nie tak definiuje się zmienne globalne.


On pisze o zmiennej publicznej:

Dunay napisał(a):zgodnie z Twoimi słowami deklaruję w Unit1.h zmienną publiczną


Zmienną publiczną deklaruje się w sekcji public. Jak rozumiem na Form2 chcesz wyświetlić zawartość zmiennej wynik, która jest deklarowana na Form1, czyli w pliku nagłówkowym dla Form1 - tutaj Unit1.h powinieneś mieć:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
public:
        String wynik;


Problem polega na tym, że Ty próbujesz pobrać zawartość tej zmiennej na Form2 w zdarzeniu OnCreate, a to zdarzenie jest wywoływane podczas tworzenia formularza, a więc w tym samym czasie gdy tworzony jest Form1 i wszystko może działać, ale tylko wtedy jeżeli zmiennej wynik przypiszesz jakąś wartość na Form1 w konstruktorze klasy lub również w zdarzeniu OnCreate dla Form1. Istotna jest tutaj kolejność zdarzeń które zachodzą.
Przypuszczam, że założyłeś iż wywołując formularz Form2 również go tworzysz, ale to nie prawda, ten formularz jest tworzony podczas uruchamiania aplikacji, a nie podczas wywoływania. By pobrać do Form2 zawartość zmiennej na starcie tego formularza, musisz to robić w zdarzeniu OnShow, dla tegoż formualrza:

Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
void __fastcall TForm2::FormShow(TObject *Sender)
{
 Edit1->Text = Form1->wynik;
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Parę problemów

Nowy postprzez polymorphism » poniedziałek, 23 kwietnia 2012, 20:01

Faktycznie, przeoczyłem to.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Parę problemów

Nowy postprzez Dunay » poniedziałek, 23 kwietnia 2012, 20:10

Panowie oba sposoby działają. Tzn i Barona z public: int suma; jak i polymorphism z extern. Problem jest, jak wspomniał wcześniej Baron, z momentem pobrania danej. Tzn. FormCreate jak i FormShow nie pobierały zmiennej bo zakończeniu wykonywania operacji na niej w Form1. Oba sposoby pobierają daną bez problemu, ale jeśli w Form2 dodałem przycisk:
KOD cpp:     UKRYJ  
void __fastcall TForm2::Button2Click(TObject *Sender)
{
Edit1->Text=IntToStr(Form1->suma);
}
//---------------------------------------------------------------------------


PS zmienną String wynik; wywaliłem bo wyszła na zbędną.
Avatar użytkownika
Dunay
Bladawiec
Bladawiec
 
Posty: 15
Dołączył(a): środa, 18 kwietnia 2012, 16:28
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Professional x86
Kompilator: C++ Builder 6
Gadu Gadu: 0
    Windows 7Chrome

Re: Parę problemów

Nowy postprzez Cyfrowy Baron » poniedziałek, 23 kwietnia 2012, 20:26

By sposób z OnShow działał w chwili uruchomienia formularza Form2 zmienna wynik na Form1 musi zawierać jakąś wartość. Jak sądzę zmiennej wynik przypisujesz jakąś wartość dopiero po zakończeniu działania zegara na Form1, czyli w chwili uruchomienia Form2 zmienna wynik nic jeszcze nie zawiera, więc nie ma czego pobierać.
Musisz śledzić kolejność zdarzeń, które zachodzą w aplikacji.

Może zamiast pobierać wartość ze zmiennej w Form2, niech Form1 wyśle zawartość zmiennej wynik do odpowiedniego obiektu na Form2, gdy zmiennej wynik zostanie przypisana jakaś wartość, np:

plik nagłówkowy Unit1.cpp
KOD cpp:     UKRYJ  
Form2->Edit1->Text = wynik;


By to zadziałało Form2 nie może być oknem modalnym, czyli nie możesz go wywoływać funkcją:

KOD cpp:     UKRYJ  
Form2->ShowModal();


lecz:

KOD cpp:     UKRYJ  
Form2->Show();


Można oczywiście też odświerzyć zdarzenie OnShow formularza Form2 gdy zmiennej zostanie przypisana wartość:

plik nagłówkowy Unit1.cpp
KOD cpp:     UKRYJ  
 wynik = "test";
 Form2->FormShow(NULL);


Jednak to zbędna komplikacja.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Dunay
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Parę problemów

Nowy postprzez Dunay » poniedziałek, 23 kwietnia 2012, 20:31

Zgadza się, teraz działa jak trzeba. Dzięki wielkie ;)
Avatar użytkownika
Dunay
Bladawiec
Bladawiec
 
Posty: 15
Dołączył(a): środa, 18 kwietnia 2012, 16:28
Podziękował : 5
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Professional x86
Kompilator: C++ Builder 6
Gadu Gadu: 0
    Windows 7Chrome

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 65 gości

cron