(gelöst) qt4.5: QObject: Cannot create children for a parent ....
-
Hallo Zusammen,
wie kann ich den folgenden Fehler umgehen.
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x95ddd60), parent's thread is QThread(0x95523e8), current thread is FortuneThread(0x9795968)Seltsamerwiese arbeitet das Programm korrekt und stürzt nicht ab (noch nicht).
Ich gehe hierbei hin und geben dem neuen Thread das erzeugt QTcpSocket
vom Server als Referenz mit.Der Thread löscht dieses Object dann auch später.
Grund war, das wenn ich ein neues Socket Objekt via Descriptor erstellt habe, das jetzt zwei Objekt mit dem Stream verbunden waren. Das hat irgendwie seltsame Effekt gehabt (nur jede Zweite Übertragung lief).
Auch das Abknipsen der Signale hat da nicht geholfen.FortuneServer::FortuneServer(QObject *parent) : QTcpServer(parent) { }
void FortuneServer::readCommandData(void) { QDataStream in(clientConnection); in.setVersion(QDataStream::Qt_4_0); if (blockSize == 0) { if (clientConnection->bytesAvailable()< (int)sizeof(quint16)) return; in >> blockSize; } if (clientConnection->bytesAvailable() < blockSize) return; in >> Command; FortuneThread *thread = new FortuneThread(clientConnection, Command); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); }
void FortuneServer::incomingConnection(int socketDescriptor) { blockSize=0; clientConnection = new QTcpSocket; if (clientConnection->setSocketDescriptor(socketDescriptor) == false) return; connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readCommandData())); }
FortuneThread::FortuneThread(QTcpSocket *Socket, const QString &ToDo) { clientConnection=Socket; Command=ToDo; }
void FortuneThread::run() { QString Message; Message=tr("You just send the command %1 to the server").arg(Command); QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_0); out << (quint16)0; out << Message ; out.device()->seek(0); out << (quint16)(block.size() - sizeof(quint16)); clientConnection->write(block); clientConnection->waitForBytesWritten(2000); delete clientConnection; exec(); }
Wie kann ich diese Fehlermeldung beseitigen. Da ansonsten der Server so in meinem Beispiel korrekt arbeitet.
Edit:
Nach zirca 5 Clients gleichzeitig (Dauerfeuer im Sekundentakt) geht dem Server die Luft aus.Vermutlich läuft noch eine Übertragung, während bereits eine angenommen wird.
Und da wird das Objekt überschrieben.Gruss
-
Dann verschieb halt das QObject in den passenden Thread.
QObject::moveToThread() ist dein Freund (schau die Doku dazu an).
Das Problem das entstehen kann, ist einfach dass SIgnals/Slots nicht im neuen Thread, sondern eben im MainThread abgearbeitet werden, und das ist nicht der Sinn eines neuen Threads
-
Hi,
ich habe mein Konzept komplett geändert und nicht mit Signals und Slots mehr gearbeitet.
Das Problem das entstehen kann, ist einfach dass SIgnals/Slots nicht im neuen Thread, sondern eben im MainThread abgearbeitet werden, und das ist nicht der Sinn eines neuen Threads
Ich dachte mir irgendwie sowas.
Vielleicht werde ich mein Beispielprogramm nochmals dahin gehend ändert.Danke für die Info.
Gruss
-
Ritchie schrieb:
Das Problem das entstehen kann, ist einfach dass SIgnals/Slots nicht im neuen Thread, sondern eben im MainThread abgearbeitet werden, und das ist nicht der Sinn eines neuen Threads
Ich dachte mir irgendwie sowas.
Vielleicht werde ich mein Beispielprogramm nochmals dahin gehend ändert.Danke für die Info.
Sry, noch etwas genauer:
Du hast für deinen Thread die run-Methode überschrieben. Wenn du darin ein "exec()" stehen hast, hat der Thread eine eigene event-loop. Das heißt, dass Objekte, die in diesem Thread erstellt wurden, insbesondere ihre SLOTS im neuen Thread abarbeiten, was den MainThread (entsteht mit QApplication::exec()), der auch für die GUI zuständig ist, entlastet. Hat jetzt dein Thread eigene Slots, die aufgerufen werden, und dein Thread-Objekt wurde aber im MainThread erstellt, hast du ein ProblemDu kannst auch Objekte erstellen und diese mittels QObject::moveToThread() in den neuen Thread verschieben, damit Eventhandling im neuen Thread geschieht.
Les dir da am besten die Doku durch.