Seite 1 von 1

Anwendung hängt bei/nach Aktualisierung eines QDockWidgets

Verfasst: 28. Oktober 2010 16:41
von bobcat
Hallo,

in meiner Anwendung steuere ich ein Gerät an, den Ablauf der Steuerung zeige ich in einem von QDockWidget abgeleiteten Fenster an. Dabei gibt's folgendes Problem: Ab und zu hält die Anwendung einfach an, d.h. der Ablauf der Gerätesteuerung wird nicht fortgesetzt, bis ich z.B. den Mauszeiger irgendwo über das Dock Window oder einen anderen Bereich meiner GUI bewege.

Wenn ich die Aktualisierung des Dock Windows, also die Statusanzeige meines Ablaufs, komplett aus der Anwendung entferne, dann läuft die Anwendung problemlos.

Ein Versuch war, mit einem QTimer alle Sekunde ein QWidget::update() auszuführen ... das führt dazu, dass die Anwendung zwar weniger oft, aber immer noch gelegentlich anhält.

Der Code sieht folgendermaßen aus:

Code: Alles auswählen

namespace Ui {
	class MyDWindow;
}

class MyDWindow : public QDockWidget
{
    Q_OBJECT

private:
    Ui::MyDWindow* ui;

public:
    MyDWindow(QWidget *parent = 0);
    ...

public slots:
    void log(const QString&);

};


MyDWindow::MyDWindow(QWidget *parent) : QDockWidget(parent), ui(new Ui::MyDWindow)
{
    ui->setupUi(this);
    ...   
}


void MyDWindow::log(const QString& text)
{
    ui->textEdit->append(text);
}

Und dann in meiner Anwendung:

Code: Alles auswählen

MyDWindow* myDWindow;
myDWindow = new MyDWindow(this);
connect(someObject, SIGNAL(someSignal(const QString&)), this, SLOT(refreshMyDWindow(const QString&));

Anwendung::refreshMyDWindow(const QString& text) 
{
myDWindow->log(text);
}

Hat jemand eine gute Idee, weshalb die Anwendung anhält bzw. wie ich es schaffe, dass die Anwendung durchläuft?

Verfasst: 28. Oktober 2010 21:12
von solarix
Im Code ist nichts Auffälliges..

Aber wo bleibt denn die Anwendung stehen, wenn du den Debugger (dem Werkzeug #1 bei der Fehlersuche (daher auch der Name)) einfach anhaltest?

BTW: falls du in "refreshMyDWindow" wirklich nur diese Zeile hast, könntest du auch gleich schreiben:

Code: Alles auswählen

  connect(someObject, SIGNAL(someSignal(const QString&)), 
             myDWindow, SLOT(log(const QString&))); 
hth..

Verfasst: 29. Oktober 2010 11:48
von bobcat
Ich habe jetzt einen Weg gefunden, den ich zwar nicht ganz verstehe, der das Problem aber zu lösen scheint ... :

In meiner Anwendung benutze ich einige Zustandsautomaten (allerdings nicht mit der QStateMachine umgesetzt), deren Ereignisse, die einen Zustandsübergang auslösen, in einer Qt::QueuedConnection abgearbeitet werden. Wenn ich nun den connect, der die Inhalte der Dock Windows updated, auch mit einer Qt::QueuedConnection ausstatte, dann läuft die Anwendung durch.

Code: Alles auswählen

connect( timer, SIGNAL(timeout()), this, SLOT(refreshMyDWindow()), Qt::QueuedConnection);
In refreshMyDWindow gibt's in meiner Anwendung mehrere Anweisungen, ich aktualisiere gleich mehrere Fenster, und auf diese Weise brauche ich nur einen connect.

refreshMyDWindow wird über einen QTimer jede Sekunde aufgerufen. In dieser Sekunde können allerdings schon mehrere Log / Status Messages an die Dock Windows geschickt worden sein. Wenn ich allerdings den QTimer weglasse und stattdessen die Log Messages, die ich an die Fenster sende, in eine Queue stelle, dann habe ich das Problem nach wie vor.

Wenn ich in VisualStudio den Debugger anhalte und weitersteppen will, dann bekomme ich die Nachricht "Kein Quellcode verfügbar"

Verfasst: 29. Oktober 2010 11:51
von Christian81
Sagen wir mal so - ein QTextEdit für die Logausgabe von zig tausend Zeilen ist nicht gerade optimal. Das ist wohl auch Dein Problem.

Verfasst: 30. Oktober 2010 14:36
von bobcat
Nein, ich glaube nicht, dass das das Problem ist, denn ich begrenze die Anzahl der Zeilen, die dargestellt werden auf aktuell 1000. Oder ist das auch schon zuviel? Was wäre denn ein geeigneteres Anzeigenelement für eine Log Ausgabe?

In den anderen Status Windows highlighte ich z.B. Tabellenzeilen, aber selbst wenn ich das Log Window ganz ausschalte und Tabellen mit wenigen 100 Zeilen habe, geht's schief ...

Verfasst: 30. Oktober 2010 14:53
von Christian81
Dann hlft wohl nur ein minimal kompilierbares Beispiel da so nicht zu ersehen ist wo das wirkliche Problem liegt...