ich hab ein kleines Problem und kann es mir nicht ganz erklären warum das so ist.
Zuerst mal meine Beschreibung des Programms:
Ich empfange in einem separaten Thread von einem Socket Daten (je Socket 20000 Koordinaten), die ich dann per Signal/Slot an den mainThread sende um sie in einer graphicsScene per addLine zu zeichnen.
Das passiert in mehreren Fenstern parallel per QStackedWidget.
Dies funktioniert soweit, obwohl es etwas schneller sein könnte. Der Flaschenhals ist eindeutig die zeichnerei im mainThread.
Als ich dann mal zufällig ein Qt-Beispiel offen hatte, stellte ich fest, dass die Geschwindigkeit des zeichnens um das 6-fache schneller war.
Nach etwas Debugging stellte ich fest, dass dies der Fall war, sobald ein Timer (20ms) lief. Also hab ich den in meinem Programm im mainThread eingebaut und siehe da, es war ebenfalls so schnell.
ABER: es wurde jetzt immer Schrittweise gezeichnet, also alle paar 100 Punkte. Dies wäre jetzt nicht so schlimm, aber der event im mainThread scheint jetzt ganz für den Timer reserviert zu sein, so dass ich jetzt nicht mehr in ein anderes Fenster während dem Zeichnen wechseln konnte, was vorher der Fall war.
Kann mir jemand erklären, was der Timer GENAU bewirkt, dass plötzlich schneller gezeichnet wird als zuvor.
Im Prinzip hat doch jeder Emfangsthread seine eigene EventLoop und läuft in einem separaten Thread und somit auch auf einem eigenen Prozessor, somit sollte doch der mainThread eh nur mit zeichnen beschäftigt zu sein.
hier ein paar Code-Fetzen:
Empfangsthread:
Code: Alles auswählen
void clientThread::run()
{
tcpSocket = new QTcpSocket();
if (!tcpSocket->setSocketDescriptor(socketDescriptor))
{
emit error(tcpSocket->error());
return;
}
else
{
emit newConnected(threadCount); // threadCount eins weniger, da ein Array mit 0 anfängt
}
threadCount++; // Anzahl der connecteten Clients 1 hochzählen
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readData()),Qt::DirectConnection);
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(discon()));
exec(); // es wird ein eigener eventLoop gestartet für den thread
}
void clientThread::readData() // liest die Daten aus dem Buffer
{
QString oneMessage;
while (tcpSocket->canReadLine())
{
oneMessage = tcpSocket->readLine();
oneMessage = oneMessage.left(oneMessage.length()-1); //ohne ENDLINE-Zeichen
emit drawNow(oneMessage); // im main thread
msleep(1); // thread wird kurz angehalten, damit gezeichnet werden kann (eventLoop ausgelöst!).
//qDebug() << oneMessage;
}
Teil vom mainThread:
Code: Alles auswählen
void QtDisplay::newClient()
{
//check for all pending new connections
while(server->hasPendingConnections())
{
//get next connection
socket = server->nextPendingConnection();
thread = new clientThread(socket->socketDescriptor(), this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(thread, SIGNAL(drawNow( QString)), this, SLOT(drawData(QString)));
thread->start( QThread::LowPriority);
}
}
void QtDisplay::drawData(QString oneMessage)
{
// das Trennzeichen ";" suchen, damit empfangener String zerpflückt werden kann
QStringList list = oneMessage.split(";");
QString canvasNameIN = list.at(0);
QString Befehlstext = list.at(1);
QString canvasName = canvasNameIN.right(canvasNameIN.length()-1); //ohne "/"-Trennzeichen
// passendes Handle zum Canvas-Fenster finden
mainCanvas *currentCanvas = pagesWidget->findChild<mainCanvas *>(canvasName);
// Parser
if (Befehlstext == "moveTo")
{
QString X1 = list.at(2);
QString Y1 = list.at(3);
double X1Value = X1.toDouble(); // umwandeln von String in Double
double Y1Value = Y1.toDouble(); // umwandeln von String in Double
canvasObj.QtMoveTo( currentCanvas->kontextPntr, X1Value, Y1Value );
}
if (Befehlstext == "LineTo")
{
QString X1 = list.at(2);
QString Y1 = list.at(3);
double X1Value = X1.toDouble(); // umwandeln von String in Double
double Y1Value = Y1.toDouble(); // umwandeln von String in Double
canvasObj.QtLineTo( currentCanvas->kontextPntr, X1Value, Y1Value );
}
}
Greetz, Paddel