QThread bringt mich zur verzweiflung
Verfasst: 27. März 2011 23:32
nachdem ich nun schon einen ganzen tag in der aktuellen Qt-doc und den installierten beispielen gestoebert habe und zudem in diversen foren gelesen habe, bin ich noch verwirrter als vorher und hoffe auf einen entsprechenden tip von euch:
ich moechte in einem getrennten Thread eine grosse Textdatei einlesen. Hierzu habe ich (entgegen der "you are doing it wrong" philosophie) QThread abgeleitet und in der run methode das ganze einlesen vorgenommen.
urspruenglich wollte ich in jedem einlese-schritt per signal slot das eingelesene datum (in diesem fall eine text-zeile aus der datei) an die gui (den hauptthread) schicken. das hat aber die gui aufgrund von sehr vielen emits aufgehangen.
mein jetziger ansatz sendet nicht nach jedem einlese-schritt ein signal sondern schiebt alles eingelesene in ein QTextDocument ein (wurde im abgeleiteten thread auf dem heap erzeugt) und schickt ganz am ende des einlesens ein signal an gui-thread, dass das einlesen zu ende ist.
nun meine frage: wie komme ich an das QTextDocument ran ??
bei meinen bisherigen versuchen gab es crashes aufgrund der tatsache dass thread uebergreifend gui geaendert wird, worauf ich mich in bezug auf QObject::moveToThread(QThread *) versucht habe aber immer noch scheitere:
mein code sieht in etwa so aus (ich schicke nur relevante teile und moechte niemanden mit dem kompletten zeug erschlagen, hoffe es hilft):
worker-thread-klasse:
implementierung von run():
das WorkDone signal ist an einen slot PutDoc aus meinem haupt-gui-thread gebunden:
meine application stuerzt immer bei ausfuehrung von setDocument(doc) ab. Ich vermute dass hat mit der thread-uebergreifenden verwendung/manipulation von gui-elementen zu tun und dass ich das mit dem moveToThread nicht ganz richtig mache.
nur verstehe ich weder die doku hierzu noch gibt es nirgends ein anstaendiges beispiel wie so eine "Datenuebertragung" von statten gehen muss.
ich bitte um tips / ideen / links.
vielen dank.
ich moechte in einem getrennten Thread eine grosse Textdatei einlesen. Hierzu habe ich (entgegen der "you are doing it wrong" philosophie) QThread abgeleitet und in der run methode das ganze einlesen vorgenommen.
urspruenglich wollte ich in jedem einlese-schritt per signal slot das eingelesene datum (in diesem fall eine text-zeile aus der datei) an die gui (den hauptthread) schicken. das hat aber die gui aufgrund von sehr vielen emits aufgehangen.
mein jetziger ansatz sendet nicht nach jedem einlese-schritt ein signal sondern schiebt alles eingelesene in ein QTextDocument ein (wurde im abgeleiteten thread auf dem heap erzeugt) und schickt ganz am ende des einlesens ein signal an gui-thread, dass das einlesen zu ende ist.
nun meine frage: wie komme ich an das QTextDocument ran ??
bei meinen bisherigen versuchen gab es crashes aufgrund der tatsache dass thread uebergreifend gui geaendert wird, worauf ich mich in bezug auf QObject::moveToThread(QThread *) versucht habe aber immer noch scheitere:
mein code sieht in etwa so aus (ich schicke nur relevante teile und moechte niemanden mit dem kompletten zeug erschlagen, hoffe es hilft):
worker-thread-klasse:
Code: Alles auswählen
// //////////////////////////////////////////
class FileLoader : public QThread
// //////////////////////////////////////////
{
Q_OBJECT
// //////////////////////////////
public:
// //////////////////////////////
FileLoader(QObject *parent);
~FileLoader();
signals:
void WorkDone(QTextDocument *);
protected:
void run();
// //////////////////////////////
private:
// //////////////////////////////
CLogFile logfile;
QTextDocument *doc;
};
Code: Alles auswählen
// //////////////////////////////////
void FileLoader::run()
// //////////////////////////////////
{
string content;
// ...
doc->moveToThread(this);
QTextCursor cursor(doc);
// hier einlesen und text mit cursor einfuegen ...
emit WorkDone(doc);
}
Code: Alles auswählen
void PutDoc(QTextDocument *doc)
{
doc->moveToThread(QApplication::instance()->thread());
ui->textEdit->setDocument(doc);
}
nur verstehe ich weder die doku hierzu noch gibt es nirgends ein anstaendiges beispiel wie so eine "Datenuebertragung" von statten gehen muss.
ich bitte um tips / ideen / links.
vielen dank.