3

私のアプリケーションでは、ダイアログに次のコードがあります。

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

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

PerformOperation関数は、最終的にシグナルを発行する関数を呼び出しますdriveFileProgressChanged私の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()してみてください。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 に答える