Я отлаживал некоторый код, который, кажется, блокирует основной поток, когда графический интерфейс не виден. Я сократил его до следующего фрагмента кода и обнаружил, что проблема связана с моей реализацией QTimer::singleShot.
Чтобы воспроизвести проблему, я установил таймер на 1 (миллисекунда), чтобы запустить цикл приложения и отправить окно приложения в фоновый режим. В конце концов приложение остановится, пока пользовательский интерфейс не будет переведен на передний план.
Если я установлю таймер на 0, он будет работать безупречно, независимо от того, где находится главное окно приложения. Я без проблем увеличил размер цикла до 4 миллионов.
Я думаю, что я застрял в том, в чем разница между
QTimer::singleShot(1, this, SLOT(emptyListOfAnotherObjects()));
и
QTimer::singleShot(0, this, SLOT(emptyListOfAnotherObjects()));
?
Почему один блокирует основной поток над другим?
Для чего стоит запускать этот цикл в другом потоке, сохраняя отдельный графический интерфейс, приводит к той же проблеме.
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()));
}
Спасибо
Обновление:
Извините, надо было добавить, что это Qt 5.2 на OSX.
.ui
и т. д., чтобы воспроизвести это, вы действительно не минимизировали этот тестовый пример, насколько это возможно. - person Kuba hasn't forgotten Monica   schedule 04.04.2016