QTcpServer closen der in einem anderen Thread läuft

Alles rund um die Programmierung mit Qt
Antworten
Rumbert
Beiträge: 48
Registriert: 25. Mai 2009 18:28
Wohnort: Witten

QTcpServer closen der in einem anderen Thread läuft

Beitrag von Rumbert »

Hallo miteinander,

folgenedes Probelm:
Ich lege einen QTCpServer an, der in einem Thread mit eigener Eventloop läuft. Das problem ist wenn ich den Server bende und die QTCPServer close bekomm ich ich meldung: "Cannot send events to objects owned by a different thread"

Ich habe versucht meinen Code aufs nötigste zu reduzieren.
Hier die Klasse, die das ThreadObjekt instanziert und damit arbeitet.

Code: Alles auswählen

class CommunicatorServerWindow : public QDialog, private Ui::CommunicatorServerWindowBase
{
   Q_OBJECT;
    ...
}

CommunicatorServerWindow::CommunicatorServerWindow()
: QDialog()
{
	setupUi(this);
	pVideoServer = NULL;
	...
}

void CommunicatorServerWindow::slotStartVideoServer()
{
	pVideoServer = new VideoServer();

	connect ( pVideoServer, SIGNAL( signalCreateStatusMessage(const QString&)),
			this, SLOT( slotCreateStatusMessage(const QString&)) );
	connect ( pVideoServer, SIGNAL( signalIncommingMessage(const QString&)),
			this, SLOT( slotIncommingMessage(const QString&)));

	pVideoServer->start();
}


void CommunicatorServerWindow::slotStopVideoServer()
{
	pVideoServer->exit(0);
//	pVideoServer->moveToThread(QApplication::instance()->thread());  // <-- Das hilft auch nichts bei meinem Problem
	pVideoServer->stopServer();

	disconnect ( pVideoServer, SIGNAL( signalCreateStatusMessage(const QString&)),
			this, SLOT( slotCreateStatusMessage(const QString&)) );
	disconnect ( pVideoServer, SIGNAL( signalIncommingMessage(const QString&)),
			this, SLOT( slotIncommingMessage(const QString&)));

	delete(pVideoServer);
	pVideoServer = NULL;
}

und hier die ServerThread-Klasse:

Code: Alles auswählen

class VideoServer : public QThread
{
	Q_OBJECT
	...
}

VideoServer::VideoServer()
: port(0)
{
	tcpServer = NULL;
	tcpServer = new QTcpServer();
    this->moveToThread(this);
}

void VideoServer::run()
{
	QString hostname = "192.168.0.100";
	int port = 5554;
  serverAddress = QHostAddress(hostname);

	if (tcpServer->listen(serverAddress, port))
	{
		connect(tcpServer, SIGNAL(newConnection()),
			this, SLOT(slotClientConnected()) );

		connect(RobotinoCom::Instance(), SIGNAL(signalSendImage(const QImage&)),
			this, SLOT(slotSendMessage(const QImage&)) );
	}
	exec();
}

void VideoServer::stopServer()
{
	if (NULL != tcpServer)
	{
		tcpServer->close();  // ### <--- hier tritt die Meldung auf
		delete (tcpServer);
		tcpServer = NULL;
	}
}
Mein Ziel ist es, dass die Slots des VideoServers in einem eigen Thread laufen, was sie so auch im Moment tun. Ich kann halt nur nicht den Server closen...

Jemand eine Idee?

Grüße Rumbert
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Ich kann halt nur nicht den Server closen...

Jemand eine Idee?
Teile dem Server mittels internem Signal mit, dass er sich zu beenden hat:

Code: Alles auswählen

void VideoServer::stopServer()
{
   emit doShutdown();
}
Dieses Signal kannst du dann mit einem Slot connecten, welcher dann im Kontext des Threads ausgeführt wird. Da kannst du dann tu und lassen, was du möchtest..

Code: Alles auswählen

void VideoServer::slotShutdown()
{
  delete tcpServer;
  ...
  ... 
  quit(); // exec() des Threads verlassen
}
BTW:

Code: Alles auswählen

VideoServer::VideoServer()
: port(0)
{
   tcpServer = NULL;
   tcpServer = new QTcpServer(); 
Das macht keinen Sinn.. erstens sind Doppelzuweisungen überflüssig, uns zweitens solltest du den Server erst dann erstellen, wenn du ihn brauchst... (in der run-Methode)


hth..
Antworten