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

时间:2012-02-20 19:57:35

标签: c++ multithreading qt qtconcurrent

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

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

我正在做一些阅读,并看到QFutureQFutureWatcher支持监控进度值(在这种情况下效果很好!),但这些不能与QtConcurrent::run一起使用

我如何将在单独线程上发出的信号连接到主线程上的插槽,以便我可以监视在发射器线程上调用的函数的进度?

* 编辑 - * 我实际上发现我的代码出错,但似乎没有影响。我忘了在信号

之后添加this作为参数
connect(drive, SIGNAL(FileProgressChanged(Progress)), this, SLOT(OnFileProgressChanged(Progress)));

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:0)

似乎问题不在于跨线程信号/槽,而在于使用参数ProgressThis问题的答案进一步详细说明,但通过在声明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&,但我在测试时将其保留。