Hallo,
ich habe eine Laufschrift als QWidget programmiert, das ich in QMainWindow einfüge. Die Schrift wird über einen Timer bewegt.
Das Problem: ich aktualisiere die Laufschrift relativ oft über eine Datenbank und dann kommt es zu "Zuckungen" in der Laufschrift.
Kann man so etwas mit einem QThread lösen? Falls ja, kann ich dann nur das Laufschrift-Widget als eigenen Thread laufen lassen und trotzdem über eine andere Klasse und Connections aktualisieren?
Gibt es noch andere Möglichkeiten, die "Zuckungen" zu vermeiden?
(ich dachte, ich könnte auch meine Aktualsierungsklasse in einen Thread auslagern, aber dann hat man soviel ich weiß Probleme mit der Datenbankverbindung, wenn sie vom "Main"-Thread ebenfalls benötigt wird)
Vielen Dank für eure Antworten!
Laufschrift/Bewegung ohne Unterbrechung - SQLite asynchron?
-
oberschlingel
- Beiträge: 85
- Registriert: 11. April 2006 09:25
- Wohnort: Berlin
Laufschrift/Bewegung ohne Unterbrechung - SQLite asynchron?
Zuletzt geändert von oberschlingel am 4. Mai 2006 21:14, insgesamt 1-mal geändert.
Hy!
Gui Operationen können nur vom Haupt-Thread aus gemacht werden, es ist also nicht möglich Teile eines Fensters direkt aus einem Thread neu zu zeichnen. Zwar können Signale und Slots über den Parameter Qt::QueuedConnection benutzt werden, so ist eine Kommunikation zwischen Thread möglich, allerdings hilft dir das auch nicht wirklich weiter.
Es können nur widgets mit einem eigenen Event-Loop laufen, vielleicht kannst du ja ein Widget so über deinem Hauptfenster plazieren, dass es den Bereich verdeckt wo du dein Widget hast, du müsstest es dann allerdings mitbewegen, also eher keine gute Lösung, bzw. hab ich keine Ahnung ob man das überhaupt Sinnvoll machen kann.
Es könnte allerdings sein das die Datenbankabfrage so lange dauert, das dadurch deine Laufschrift zu ruckeln beginnt. In diesem Fall könntest du die Datenbankabfrage regelmässig in einem eigenen Thread laufen lassen, und sollte sich der Text geändert haben eine Member Variable des Thread, oder einen andere QString den neuen Text setzen. Damit sparst du dir in deinem Gui-Thread die Zeit für die Datenbankabfrage, die maximale Wartezeit die entsteht ist, wenn du in deinem Thread gerade einen Mutex sperrst, der zum Schutz des QString da ist, und der Gui-Thread warten muss bis dieser wieder frei gegeben ist. Das sollte aber relativ kurz sein, da:
Die Zeit sollte auch noch drin sein, die gesamte Datenbankabfrage fällt jedenfalls weg. Soweit ich weis sollten die Datenbanken sich aus mehreren Threads ohne Probleme benutzen lassen, bin aber gerade noch am schauen...
mfg
uhu01
Gui Operationen können nur vom Haupt-Thread aus gemacht werden, es ist also nicht möglich Teile eines Fensters direkt aus einem Thread neu zu zeichnen. Zwar können Signale und Slots über den Parameter Qt::QueuedConnection benutzt werden, so ist eine Kommunikation zwischen Thread möglich, allerdings hilft dir das auch nicht wirklich weiter.
Es können nur widgets mit einem eigenen Event-Loop laufen, vielleicht kannst du ja ein Widget so über deinem Hauptfenster plazieren, dass es den Bereich verdeckt wo du dein Widget hast, du müsstest es dann allerdings mitbewegen, also eher keine gute Lösung, bzw. hab ich keine Ahnung ob man das überhaupt Sinnvoll machen kann.
Es könnte allerdings sein das die Datenbankabfrage so lange dauert, das dadurch deine Laufschrift zu ruckeln beginnt. In diesem Fall könntest du die Datenbankabfrage regelmässig in einem eigenen Thread laufen lassen, und sollte sich der Text geändert haben eine Member Variable des Thread, oder einen andere QString den neuen Text setzen. Damit sparst du dir in deinem Gui-Thread die Zeit für die Datenbankabfrage, die maximale Wartezeit die entsteht ist, wenn du in deinem Thread gerade einen Mutex sperrst, der zum Schutz des QString da ist, und der Gui-Thread warten muss bis dieser wieder frei gegeben ist. Das sollte aber relativ kurz sein, da:
Code: Alles auswählen
hole string aus datenbank;
wenn( neuerstring != alterstring)
mutex.lock;
memberstring = neuerstring;
mutex.unlock;
loop;
mfg
uhu01
-
oberschlingel
- Beiträge: 85
- Registriert: 11. April 2006 09:25
- Wohnort: Berlin
Zuerst mal vielen Dank für die ausführliche Antwort uhu01!
Ich habe nochmal etwas genauer geforscht und herausbekommen, dass der Grund an meiner SQLite-DB liegt. Diese arbeitet synchron mit einem File auf der Festplatte, daher wird nach jedem Zugriff gewartet, bis die Festplatte den Zugriff beendet hat. So kommen die Verzögerungen zustande.
Habe meine Klasse nun verändert, jetzt rufe ich im Konstruktor eine Funktion auf, die den SQL-Befehl
ausführt. Das funktioniert jetzt prima.
Aber nun frage ich mich folgendes:
Da ich auch jede Menge INSERT-Befehle ausführe und diese nun ebenfalls asynchron laufen - kann es mir auf einem langsam Rechner passieren, dass sich die DB-Zugriffe quasi "überschneiden" und so INSERT-Befehle "verschluckt" werden oder Fehler entstehen können?
DANKE
Ich habe nochmal etwas genauer geforscht und herausbekommen, dass der Grund an meiner SQLite-DB liegt. Diese arbeitet synchron mit einem File auf der Festplatte, daher wird nach jedem Zugriff gewartet, bis die Festplatte den Zugriff beendet hat. So kommen die Verzögerungen zustande.
Habe meine Klasse nun verändert, jetzt rufe ich im Konstruktor eine Funktion auf, die den SQL-Befehl
Code: Alles auswählen
PRAGMA synchronous=OFF;Aber nun frage ich mich folgendes:
Da ich auch jede Menge INSERT-Befehle ausführe und diese nun ebenfalls asynchron laufen - kann es mir auf einem langsam Rechner passieren, dass sich die DB-Zugriffe quasi "überschneiden" und so INSERT-Befehle "verschluckt" werden oder Fehler entstehen können?
DANKE
-
oberschlingel
- Beiträge: 85
- Registriert: 11. April 2006 09:25
- Wohnort: Berlin
Mehr Informationen als diese habe ich nicht gefunden. Sagt mir aber nicht, ob auch ein häufiger DB-Zugriff mit Inserts Probleme verursachen kann.
Quelle: http://www.sqlite.org/pragma.html
With synchronous OFF (0), SQLite continues without pausing as soon as it has handed data off to the operating system. If the application running SQLite crashes, the data will be safe, but the database might become corrupted if the operating system crashes or the computer loses power before that data has been written to the disk surface. On the other hand, some operations are as much as 50 or more times faster with synchronous OFF.
Quelle: http://www.sqlite.org/pragma.html
With synchronous OFF (0), SQLite continues without pausing as soon as it has handed data off to the operating system. If the application running SQLite crashes, the data will be safe, but the database might become corrupted if the operating system crashes or the computer loses power before that data has been written to the disk surface. On the other hand, some operations are as much as 50 or more times faster with synchronous OFF.