使用QtConcurrent::run连接单独线程上的信号/插槽

Connecting signals/slots on separate thread using QtConcurrent::run

本文关键字:信号 插槽 单独 QtConcurrent run 连接 使用 线程      更新时间:2023-10-16

在我的应用程序中,对话框中有以下代码:

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)));

尝试将connect()QueuedConnection一起使用,如:

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

默认情况下,连接应该已经排队(因为发射器和接收器在不同的线程中),但这只会使其更加明确。

编辑:问题是Progress类型没有在Qt的元对象系统中注册。添加qRegisterMetaType<Progress>("Progress");解决了问题。

问题似乎不在于跨线程信号/插槽,而在于参数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&,但我在测试时留下了它。