Programm führ Abfrage - Wie TTimer immer wieder neu aufrufen?
-
Hallo akari,
danke für deine Tipps. Also muss ich das in einen Thread auslagern. Sowas habe ich bisher aber nocht nicht gemacht. Kannst du mir sagen, wie ich sowas mache? Oder wo ich mir darüber ein paar Tipps holen kann?Danke im voraus.
-
-
Falls du RAD Studio 2009 verwendest gibts es bei der
TProgressBar den Style pbstMarquee
-
Hallo,
ich habe mir das Tutorial von hier durchgelesen und versucht es für mich umzubauen. Leider habe ich noch immer das gleiche Problem. Es wird mir erst angezeigt, nachdem die Abfrage durchlaufen ist.Hier meine TThread.cpp
__fastcall TProcessBarThread::TProcessBarThread(bool CreateSuspended) : TThread(CreateSuspended) { } //--------------------------------------------------------------------------- void __fastcall TProcessBarThread::GuiElements() { //Da wir uns nicht im Gültigkeitsbereich von Form1 befinden, müssen wir qualifizieren mit Form1. statistik_palettenplaetze->Tprogress->Enabled = true; // Hier rufe ich den Timer auf } //--------------------------------------------------------------------------- void __fastcall TProcessBarThread::Execute() { Synchronize(&GuiElements); }
So rufe ich den Thread auf
new TProcessBarThread(false); AnsiString sql_select = "SELECT * from lagerplatze where ort = 'regal' order by bezeichnung"; DataModule1->sql_select->SQL->Clear(); DataModule1->sql_select->SQL->Add(sql_select); DataModule1->sql_select->Open(); lagerplatz_gesamt = DataModule1->sql_select->RecordCount; while(!DataModule1->sql_select->Eof) {
Wo könnte da jetzt mein Fehler liegen? Darf ich das nicht mehr über den Timer laufen lassen?
-
Hallo,
das TTimer-Event muss auch im Thread abgearbeitet werden...
MfG
-
Das mache ich doch. In der TThread.cpp rufe ich folgendes auf
void __fastcall TProcessBarThread::GuiElements() { //Da wir uns nicht im Gültigkeitsbereich von Form1 befinden, müssen wir qualifizieren mit Form1. statistik_palettenplaetze->Tprogress->Enabled = true; // Hier rufe ich den Timer auf }
Oder was meinst du damit, dass es im Thread abgearbeitet werden muss?
-
EPMS schrieb:
Das mache ich doch. In der TThread.cpp rufe ich folgendes auf
statistik_palettenplaetze->Tprogress->Enabled = true; // Hier rufe ich den Timer auf
Damit startest du den Timer lediglich vom Thread aus.
EPMS schrieb:
Oder was meinst du damit, dass es im Thread abgearbeitet werden muss?
Ich meine das OnTimer-Event sollte in den Thread::Execute-Bereich gelegt werden. Der Thread ist in diesem Fall dazu da, dass gewissermaßen parallel zum normalen Programmablauf deine Fortschrittsanzeige / Arbeitsanzeige aktualisiert wird. Also musst du die entsprechende Verarbeitung in den Thread schieben.
-
Also, ich habe jetzt folgendes in der Thread.cpp
void __fastcall TProcessBarThread::GuiElements() { //Da wir uns nicht im Gültigkeitsbereich von Form1 befinden, müssen wir qualifizieren mit Form1. statistik_palettenplaetze->Pprogress->Visible = true; if(statistik_palettenplaetze->Pbalken->Left > 114) { statistik_palettenplaetze->Pbalken->Left = -10; } statistik_palettenplaetze->Pbalken->Left = statistik_palettenplaetze->Pbalken->Left + 4; } //--------------------------------------------------------------------------- void __fastcall TProcessBarThread::Execute() { Synchronize(&GuiElements); }
Ich habe den Timer jetzt mal weggelassen. Einfach um zu sehen, ob das anzeigen des Panel überhaupt klappt. Aber das funktioniert auch nicht. Es wird erst angezeigt, wenn die Abfrage bearbeitet wurden ist.
Bin glaube ich zu blöd dafür.
Weiß nicht, wo da der Fehler liegt....
-
EPMS schrieb:
Bin glaube ich zu blöd dafür.
Weiß nicht, wo da der Fehler liegt....
Nein, ich glaube der Weg stimmt - wir sind nur noch nicht am Ziel.
Geh mal mit dem Debugger ab Thread-Erstellung schrittweise durch... Wann kommst du in Zeile 3 des zuletzt geposteten Code an? Ich vermute Zeile 3 wird vor der Abfrage ausgeführt, aber das Panel einfach noch nicht gezeichnet...
-
Also, die Abfrage starte ich mit einem klick auf einen Button. Die von dir angesprochene dritte Zeile wird erst nach dem letzten Befehl der Button-Routine aufgerufen. Also doch viel zu Spät oder nicht?
-
Ein Application->ProcessMessages() direkt nach der Erstellung des Thread müsste helfen... Ob das die finale Lösung für dein Gesamtproblem ist, kann ich allerdings nicht sagen.
-
Ok, damit wird das Panel sofort angezeigt.
Jetzt komme ich wieder zu deinem Satz
Ich meine das OnTimer-Event sollte in den Thread::Execute-Bereich gelegt werden.
Wie lege ich das OnTimer-Event in den Thread::Execute-Bereich?
-
Wie ich inzwischen weiß, ist es sinnfrei visuelle Komponenten (zB. Panels) in Threads zu manipulieren (zB. wie bei dir die Position des Panels zu verändern), da die Abarbeitung bei visuellen Komponenten trotzdem im Hauptthread (dein Programm ist der Hauptthread) ausgeführt und der Thread angehalten wird (das erledigt Synchronize)... kurz: Die Darstellung würde wahrscheinlich immernoch nicht wie gewünscht sein.
Du solltest also die Datenbank-Abfrage in den Thread legen und die Statusanzeige direkt im Form realisieren. Du musst den Thread dann nur irgendwie informieren, dass der Button gedrückt wurde... da hörts leider langsam auf mit meinem Verständnis... jetzt müssen wieder Andere helfen.
MfG
Edit: Du könntest den Thread als Suspended erstellen, ihn im Button-Click starten und er könnte sich nach einem Durchlauf (die entsprechende Abfrage) selbst beenden.
-
Moin,
ich habe die Abfrage jetzt in den Thread gelegt und rufe das Panel im Hauptprogramm auf. Damit klappt es wunderbar. Danke für deine Hilfe.