GUI friert ein
-
reinki0013
- Beiträge: 174
- Registriert: 11. November 2008 09:37
- Wohnort: AUT
GUI friert ein
hallo zusammen,
ich habe ein programm, welches dateien an einen ftp-server sendet.
in diesem zuge habe ich auch einen fortschrittsbalken gemacht. ich habe jetzt allerdings das problem, z.b. mit windows 7 friert mir die GUI ein sobald ich außerhalb des Programms wo hinklicke. Bei einem weiteren klick kommt sofort die meldung (keine Rückmeldung) und der Inhalt meiner GUI wird weiß...
hat da jemand schon erfahrungen in diese richtung gemacht bzw. kann mir da jemand weiterhelfen?
lg
ich habe ein programm, welches dateien an einen ftp-server sendet.
in diesem zuge habe ich auch einen fortschrittsbalken gemacht. ich habe jetzt allerdings das problem, z.b. mit windows 7 friert mir die GUI ein sobald ich außerhalb des Programms wo hinklicke. Bei einem weiteren klick kommt sofort die meldung (keine Rückmeldung) und der Inhalt meiner GUI wird weiß...
hat da jemand schon erfahrungen in diese richtung gemacht bzw. kann mir da jemand weiterhelfen?
lg
Re: GUI friert ein
Wenn du uns zeigst, wie du es machst (Code!) können wir dir vielleicht sagen, was du ändern kannst, damit es funktioniert.
Da ich nicht weiß, unter welchen Umständen Windows diese Meldung raushaut, kann ich nur in Richtung "du hängst in einer blockierende Funktion" mutmaßen.
Da ich nicht weiß, unter welchen Umständen Windows diese Meldung raushaut, kann ich nur in Richtung "du hängst in einer blockierende Funktion" mutmaßen.
-
reinki0013
- Beiträge: 174
- Registriert: 11. November 2008 09:37
- Wohnort: AUT
Re: GUI friert ein
hi,
also ich habe einen QTcpSocket und einen QTextStream.
in einer while-schleife schicke ich die daten von meinem QTextStream an meinen QTcpSocket bis nichts mehr im QTextStream drinnen steht.
Währenddessen friert mir dann die GUI ein, wenn ich während dieser Schleife etwas anderes mache bzw. wo anders hinklicke...
hiflt dir das schon weiter?
sonst hier der code von der funktion
lg
also ich habe einen QTcpSocket und einen QTextStream.
in einer while-schleife schicke ich die daten von meinem QTextStream an meinen QTcpSocket bis nichts mehr im QTextStream drinnen steht.
Währenddessen friert mir dann die GUI ein, wenn ich während dieser Schleife etwas anderes mache bzw. wo anders hinklicke...
hiflt dir das schon weiter?
sonst hier der code von der funktion
Code: Alles auswählen
bool eModem::Send(QString Name, QByteArray data)
{
out << "re\r";
out.flush();
sock.waitForReadyRead(3000); // max. 3 Sekunden warten
QString empfang;
while(!in.atEnd())
{
in >> empfang;
if(empfang == "start")
{
quint32 len = data.size();
qint64 maxlen = len;
qint64 pos = 0;
out << Name << '\0' << len << '\0';
out.flush();
while(len)
{
sock.waitForReadyRead(10000);
in >> empfang;
if(empfang.size() == 0)
return false;
if(empfang == "fin")
pos = maxlen;
else
pos = empfang.toInt();
emit Progress(pos, maxlen);
len = data.size();
if(len > 512)
len = 512;
QByteArray buf;
buf.append(data.constData(), len);
data.remove(0, len);
sock.write(buf);
//out << buf; // out funktioniert nicht wegen TextStream
//out.flush();
sock.flush();
sock.waitForBytesWritten(3000);
}
return true;
}
}
return false;
}lg
Re: GUI friert ein
QIODevice::waitForReadyRead() ist blockierend, deine Gui reagiert nicht. Es steht auch noch ganz klar dabei:
Du hast auch ganz schön lange Timeouts gesetzt, in jedem Durchlauf der inneren Schleife blockierst du zusammen 13 Sekunden.
Also: entweder lagerst du das ganze in nen eigenen Thread aus, oder du nimmst gleich die asynchrone API (also über SIGNAL/SLOT), letzteres wäre die zu bevorzugende Methode.It is useful when writing non-GUI applications and when performing I/O operations in a non-GUI thread.
Du hast auch ganz schön lange Timeouts gesetzt, in jedem Durchlauf der inneren Schleife blockierst du zusammen 13 Sekunden.
-
GottfriedSp
- Beiträge: 4
- Registriert: 18. Oktober 2010 12:57
Re: GUI friert ein
In der Schleife ist ein
Welcher das Signal zum Slot in das Hauptfenster leitet und damit der Fortschrits-Balken aktualisiert wird (ca. 500ms pro Aktualisierung).
Das Programm funktioniert im Debug-Modus perfekt, allerdings das Release funktioniert nicht.
Bei Windows XP funktioniert sogar das Release noch so einigermassen.
Mit Thread hatten wir es auch schon versucht, welcher bei Windows 7 mit dem Debug-Binaries perfekt funktioniert, allerdings bei Release wird der QMutex irgend wie nicht beachtet oder durchgeführt. (statische QMutex).
Wir haben die 4.7.4 und 4.7.1
Code: Alles auswählen
emit Progress(pos, maxlen);Das Programm funktioniert im Debug-Modus perfekt, allerdings das Release funktioniert nicht.
Bei Windows XP funktioniert sogar das Release noch so einigermassen.
Mit Thread hatten wir es auch schon versucht, welcher bei Windows 7 mit dem Debug-Binaries perfekt funktioniert, allerdings bei Release wird der QMutex irgend wie nicht beachtet oder durchgeführt. (statische QMutex).
Wir haben die 4.7.4 und 4.7.1
-
reinki0013
- Beiträge: 174
- Registriert: 11. November 2008 09:37
- Wohnort: AUT
Re: GUI friert ein
Kann uns beiden wer einen Tipp geben?
-
reinki0013
- Beiträge: 174
- Registriert: 11. November 2008 09:37
- Wohnort: AUT
Re: GUI friert ein
also ich habs jetzt mal probiert mit QThread - aber da bin ich überfordert...
ich habe jetzt folgendermaßen probiert:
das funktioniert aber leider auch nicht - die GUI friert trotzdem ein beim Release...
lg
ich habe jetzt folgendermaßen probiert:
Code: Alles auswählen
bool eModem::Send(QString Name, QByteArray data)
{
QThread *thread = new QThread;
this->moveToThread(thread);
thread->start();
out << "re\r";
out.flush();
sock.waitForReadyRead(3000); // max. 3 Sekunden warten
QString empfang;
while(!in.atEnd())
{
in >> empfang;
if(empfang == "start")
{
quint32 len = data.size();
qint64 maxlen = len;
qint64 pos = 0;
out << Name << '\0' << len << '\0';
out.flush();
while(len)
{
sock.waitForReadyRead(10000);
in >> empfang;
if(empfang.size() == 0)
return false;
if(empfang == "fin")
pos = maxlen;
else
pos = empfang.toInt();
emit Progress(pos, maxlen);
len = data.size();
if(len > 512)
len = 512;
QByteArray buf;
buf.append(data.constData(), len);
data.remove(0, len);
sock.write(buf);
//out << buf; // out funktioniert nicht wegen TextStream
//out.flush();
sock.flush();
sock.waitForBytesWritten(3000);
}
return true;
}
}
return false;
}lg
Re: GUI friert ein
Du startest zwar jetzt tatsächlich einen Thread, der hat aber nichts mit dem zu tun, was Deine eModem Klasse macht. Du müsstest Deine gesamte eModem Klasse in eine von QThread abgeleitete Klasse überführen.
Aber das ist eigentlich auch gar nicht notwendig. Wie franzf gesagt hat, bietet QTcpSocket ja schon alles, was Du für asynchrone Kommunikation brauchst (über QIODevice). Du musst in eModem auf das readyRead() Signal des Sockets reagieren und erst dann aus dem Socket lesen, wenn es ankommt. Ein Mögliches Timeout solltest Du dann allerdings selbst implementieren über einen QTimer, den Du jedesmal beim Empfangen von Daten killst und nach dem Senden neuer Daten anwirfst. Wenn der Timer irgendwann feuert, kappst Du die Verbindung, damit der Server auch bescheid weiß.
Aber das ist eigentlich auch gar nicht notwendig. Wie franzf gesagt hat, bietet QTcpSocket ja schon alles, was Du für asynchrone Kommunikation brauchst (über QIODevice). Du musst in eModem auf das readyRead() Signal des Sockets reagieren und erst dann aus dem Socket lesen, wenn es ankommt. Ein Mögliches Timeout solltest Du dann allerdings selbst implementieren über einen QTimer, den Du jedesmal beim Empfangen von Daten killst und nach dem Senden neuer Daten anwirfst. Wenn der Timer irgendwann feuert, kappst Du die Verbindung, damit der Server auch bescheid weiß.
-
GottfriedSp
- Beiträge: 4
- Registriert: 18. Oktober 2010 12:57
Re: GUI friert ein
Das mit readyRead() funktioniert einwandfrei!
Auf die Einfachsten Dinge kommt man immer zuletzt
Auf die Einfachsten Dinge kommt man immer zuletzt