问题
In my application I have the following code in a dialog:
connect(drive, SIGNAL(FileProgressChanged(Progress)), SLOT(OnFileProgressChanged(Progress)));
QtConcurrent::run(this, &ProgressDialog::PerformOperation, Operation, *Path, OutPath, drive);
The PerformOperation function eventually calls to a function in drive
which emits the signal FileProgressChanged
, and my OnFileProgressChanged
function is as follows:
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));
}
I was doing some reading and saw that QFuture and QFutureWatcher support monitoring progress values (which would work great in this situation!), but those cannot be used in conjunction with QtConcurrent::run
.
How would I go about connecting the signal that gets moved emitted on the separate thread to the slot on my main thread so I can monitor the progress of the function called on the emitter thread?
*Edit -- * I actually found an error with my code, but it doesn't seem to have an affect. I forgot to add this
as an argument after the signal
connect(drive, SIGNAL(FileProgressChanged(Progress)), this, SLOT(OnFileProgressChanged(Progress)));
回答1:
Try using connect()
with QueuedConnection
, like:
connect(drive, SIGNAL(FileProgressChanged(Progress)), this, SLOT(OnFileProgressChanged(Progress)), Qt::QueuedConnection);
The connection should already be queued by default (since the emitter and receiver are in different threads), but this just makes it more explicit.
EDIT: The problem was that the Progress
type wasn't registered with Qt's meta-object system. Adding qRegisterMetaType<Progress>("Progress");
fixed the problem.
回答2:
It appears as though the problem isn't with the cross-thread signal/slot, but instead with the parameter Progress
. This question's answer goes into further detail, but the solution was found by doing the following in the header file in which Progress was declared:
struct Progress
{
int Current;
int Maximium;
std::string FilePath;
std::string FolderPath;
int TotalMinimum;
int TotalMaximum;
};
Q_DECLARE_METATYPE(Progress)
And in my form class:
qRegisterMetaType<Progress>();
connect(Drive, SIGNAL(FileProgressChanged(const Progress&)), this, SLOT(OnFileProgressChanged(const Progress&)), Qt::QueuedConnection);
Changing Progress
to const Progress&
most likely isn't needed but I left it while testing.
来源:https://stackoverflow.com/questions/9367582/connecting-signals-slots-on-separate-thread-using-qtconcurrentrun