Соединение сигналов / слотов в отдельном потоке с помощью QtConcurrent :: run - PullRequest
2 голосов
/ 20 февраля 2012

В моем приложении у меня есть следующий код в диалоге:

connect(drive, SIGNAL(FileProgressChanged(Progress)), SLOT(OnFileProgressChanged(Progress)));

QtConcurrent::run(this, &ProgressDialog::PerformOperation, Operation, *Path, OutPath, drive);

Функция PerformOperation в конечном итоге вызывает функцию в drive, которая излучает сигнал FileProgressChanged, а моя функция OnFileProgressChanged выглядит следующим образом:

void ProgressDialog::OnFileProgressChanged(Progress p)
{
    if (ui->progressCurrent->maximum() != p.Maximium)
        ui->progressCurrent->setMaximum(p.Maximium);

    ui->progressCurrent->setValue(p.Current);

    if (ui->groupBoxCurrent->title().toStdString() != p.FilePath)
        ui->groupBoxCurrent->setTitle(QString::fromStdString(p.FilePath));
}

Я немного читал и увидел, что QFuture и QFutureWatcher поддерживают мониторинг значений прогресса (что прекрасно работает в этой ситуации!), Но их нельзя использовать вместе с QtConcurrent::run.

Как мне подключить передаваемый сигнал, излучаемый в отдельном потоке, к слоту основного потока, чтобы я мог отслеживать ход выполнения функции, вызываемой в потоке эмиттера?

* Редактировать - * На самом деле я обнаружил ошибку с моим кодом, но, похоже, это не влияет. Я забыл добавить this в качестве аргумента после сигнала

connect(drive, SIGNAL(FileProgressChanged(Progress)), this, SLOT(OnFileProgressChanged(Progress)));

Ответы [ 2 ]

1 голос
/ 21 февраля 2012

Попробуйте использовать connect() с QueuedConnection, например:

connect(drive, SIGNAL(FileProgressChanged(Progress)), this, SLOT(OnFileProgressChanged(Progress)), Qt::QueuedConnection);

Соединение уже должно быть поставлено в очередь по умолчанию (поскольку излучатель и приемник находятся в разных потоках), но это только делает его болееявное.

РЕДАКТИРОВАТЬ: Проблема заключалась в том, что тип Progress не был зарегистрирован в мета-объектной системе Qt.Добавление qRegisterMetaType<Progress>("Progress"); решило проблему.

0 голосов
/ 21 февраля 2012

Похоже, что проблема не в перекрестном сигнале / слоте, а в параметре Progress. Ответ на этот вопрос детализируется, но решение было найдено с помощью следующего в заголовочном файле, в котором был объявлен Progress:

struct Progress
{
    int Current;
    int Maximium;
    std::string FilePath;
    std::string FolderPath;
    int TotalMinimum;
    int TotalMaximum;
};

Q_DECLARE_METATYPE(Progress)

И в моем классе формы:

qRegisterMetaType<Progress>();
    connect(Drive, SIGNAL(FileProgressChanged(const Progress&)), this, SLOT(OnFileProgressChanged(const Progress&)), Qt::QueuedConnection);

Изменение Progress на const Progress&, скорее всего, не нужно, но я оставил его во время тестирования.

...