В дополнение к комментариям, касающимся дизайна и чтения имен файлов из потока GUI перед созданием другого и передачей дескрипторов в качестве аргументов, я понимаю, что могут быть некоторые сценарии, в которых вам нужно вызывать диалоги 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 (*.*)");
person
cbuchart
schedule
03.11.2017