Ich habe einige Code debuggen, der den Haupt-Thread zu sperren scheint, wenn die GUI nicht sichtbar ist. Ich habe es direkt zurück zu dem folgenden Codeausschnitt entfernt und ich habe festgestellt, dass ein Problem um meine Implementierung von QTimer :: singleShot besteht.Warum blockiert QTimer :: singleShot meinen Haupt-Thread zur Zeit 1, aber nicht 0
Um das Problem zu replizieren, setze ich den Timer auf 1 (Millisekunde) starten Sie die Anwendung Schleife und senden Sie das App-Fenster an den Hintergrund. Schließlich wird die App zum Stillstand kommen, bis die Benutzeroberfläche in den Vordergrund gebracht wird.
Wenn ich den Timer auf 0 setze, dann läuft das einwandfrei, egal wo sich das Haupt-App-Fenster befindet, ich habe die Loop-Größe bis auf 4 Millionen ohne Problem erhöht.
ich denke, ich bin fest, was mit ist, was der Unterschied zwischen
QTimer::singleShot(1, this, SLOT(emptyListOfAnotherObjects()));
und
QTimer::singleShot(0, this, SLOT(emptyListOfAnotherObjects()));
ist?
Warum blockiere ich den Hauptfaden über den anderen?
Für das, was es wert ist, diese Schleife in einem anderen Thread auszuführen, führt das Beibehalten der GUI zu demselben Problem.
class AnotherObject : public QObject
{
Q_OBJECT
public:
AnotherObject();
void process();
signals:
void done();
};
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void start(bool);
private slots:
void emptyListOfAnotherObjects();
void delayEmptyOfAnotherObject();
private:
QList<AnotherObject*> m_listOfAnotherObject;
Ui::MainWindow *ui;
};
==
AnotherObject::AnotherObject()
{
qDebug() << "CTOR AnotherObject" << this;
}
void AnotherObject::process()
{
emit done();
deleteLater();
}
//==
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->start, SIGNAL(clicked(bool)), this, SLOT(start(bool)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::start(bool)
{
for(long i=0; i<40000; i++){
m_listOfAnotherObject.append(new AnotherObject());
}
emptyListOfAnotherObjects();
}
void MainWindow::emptyListOfAnotherObjects()
{
if(m_listOfAnotherObject.isEmpty()) {
qDebug() << "List empty, done.";
return;
}
AnotherObject* i = m_listOfAnotherObject.takeFirst();
connect(i, SIGNAL(done()), this, SLOT(delayEmptyOfAnotherObject()));
i->process();
qDebug() << m_listOfAnotherObject.count();
}
void MainWindow::delayEmptyOfAnotherObject()
{
QTimer::singleShot(1, this, SLOT(emptyListOfAnotherObjects()));
}
Dank
Update:
Es sollte hinzugefügt, dass dies Qt 5.2 auf OSX.
Ich habe Ihren Code ausprobiert und kann Ihr Problem nicht reproduzieren. Alles funktioniert gut bei 0 und 1ms. Was meinst du mit "Senden der App an den Hintergrund"? Ich habe viele Sachen ausprobiert, aber es scheint flüssig zu laufen. – Paraboloid87
@aManFromOuterSpace - Auf welcher Plattform testen Sie dies? Wenn Sie OS X verwenden, kann es aufgrund von [App Nickerchen] sein (https://developer.apple.com/library/mac/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/AppNap.html) – TheDarkKnight
Sobald das Hauptfenster kommt Vordergrund Ich klicke auf eine Schaltfläche, um die Schleife zu starten, dann klicke auf ein anderes geöffnetes Fenster, QtCreator in meinem Fall, und bringe diese App in den Vordergrund und meine App geht nach hinten. – aManFromOuterSpace