3

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

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

2 回答 2

1

尝试使用connect()with QueuedConnection,例如:

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

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

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

于 2012-02-21T00:47:25.497 回答
0

似乎问题不在于跨线程信号/插槽,而在于参数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&

于 2012-02-21T01:00:22.257 回答