Виджет ввода в QApplication в выделенном потоке вызывает остановку QTimer из неправильного потока - PullRequest
2 голосов
/ 15 октября 2019

По разным причинам я должен создать QApplication, который не живет в основном потоке моей программы. Это работает хорошо, за исключением части очистки. По окончании main() я получаю следующее уведомление:

QObject::~QObject: Timers cannot be stopped from another thread

Это происходит довольно давно после того, как все виджеты и окна Qt, а также QApplicationбыли утилизированы.

Я сузил проблему до этого минимального примера:

#include <thread>

#include <QApplication>
#include <QLineEdit>

int main(int argc, char * argv[])
{
    std::thread t { 
        [&] {
            QApplication app{argc, argv};

            QLineEdit w{"Test"};
            w.showNormal();

            app.exec();
        }
    };

    std::this_thread::sleep_for(std::chrono::seconds{3});

    QApplication::instance()->quit();

    t.join();

    return 0;
}

A QSpinBox вместо QLineEdit приводит к тому же поведению. Когда я использую QLabel, предупреждение не выдается. Поэтому я подозреваю, что виновником является таймер, ответственный за мигание курсора, но я могу ошибаться.

Есть ли способ правильно остановить этот (невидимый) таймер при выходе из QApplication?

Ответы [ 2 ]

2 голосов
/ 15 октября 2019

Я также был бы рад опубликовать что-то вроде QuitEvent в цикле событий приложения вместо непосредственного вызова quit ().

Вот, пожалуйста,

QMetaObject::invokeMethod(QApplication::instance(), "quit", Qt::QueuedConnection);
1 голос
/ 15 октября 2019

Вам не разрешен доступ к виджетам и другим связанным элементам из любого места, кроме основного потока. Это характерно почти для всех систем с графическим интерфейсом (например, MFC, BGI, ...). Для Qt есть подсказка об этом в документации . Удивительно, но в рабочих потоках не допускается даже QPixmap.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...