В дополнение к комментариям относительно дизайна и чтения имен файлов из потока GUI перед созданием другого и передачей дескрипторов в качестве аргументов, я понимаю, что это могут быть некоторые сценарии, в которых вам нужно вызывать диалоговые окна графического интерфейса из других потоков.
Одним из решений может быть излучение сигнала из потока и захват в графическом интерфейсе. Недостатком этого подхода является то, что получить результат может быть сложно (имя файла в вашем случае).
Аналогичным решением является использование метода Qt::BlockingQueuedConnection
для вызова метода объекта, живущего в потоке графического интерфейса пользователя, при блокировке другого потока до тех пор, пока метод не вернется.
Следующий пример иллюстрирует это с помощью вспомогательного объекта:
class FileDialogCaller : public QObject {
Q_OBJECT
public:
FileDialogCaller(QObject* parent = 0) : QObject(parent) {
// The helper object will live in the GUI thread
moveToThread(qApp->thread());
}
// Add the rest of parameters as needed
QString getSaveFileName(QWidget* parent, const QString& caption, const QString& dir,
const QString& filter) {
QString fileName;
if (QThread::currentThread() != qApp->thread()) { // no GUI thread
QMetaObject::invokeMethod(this, "getSaveFileName_", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QString, fileName),
Q_ARG(QWidget*, parent),
Q_ARG(QString, caption),
Q_ARG(QString, dir),
Q_ARG(QString, filter));
} else { // in GUI thread, direct call
fileName = getSaveFileName_(parent, caption, dir, filter);
}
return fileName;
}
private:
Q_INVOKABLE
QString getSaveFileName_(QWidget* parent, const QString& caption, const QString& dir,
const QString& filter) {
return QFileDialog::getSaveFileName(parent, caption, dir, filter);
}
};
Чтобы использовать это просто:
QString fileName = FileDialogCaller().getSaveFileName(nullptr, "Save", "", "Any (*.*)");
Вы, вероятно, хотите проверить, что 'QThread :: currentThread() = qApp-> нить!() 'перед использованием Qt :: BlockingQueuedConnection. Просто позвоните 'getSaveFileName_' в этом случае – Caleth
@Caleth Конечно! он принимал сценарий OP, но я согласен с вашим предложением – cbuchart