QInputDialog에 대한 질문이 있습니다. 나는 지난 3 일을 구글에서 보냈다. 나는 대답을 찾을 수 없기 때문에 여기에서 물어볼 시간이라고 생각했다.QInputDialog & Threading (작업자, 대화 상자 표시, 입력 대기, 계속)
내 응용 프로그램에는 주 스레드 (Qt의 GUI 스레드라고도 함)가 있습니다. 이 GUI 스레드는 작업자를 생성합니다. 다른 스레드에서 실행되는 것입니다. 이 작업자는 폴더를 검사합니다. 또한 진행에 대한 GUI 스레드 정보를 보냅니다. 잘 작동합니다.
이제 여기에 문제가 있습니다. 작업자 스레드는 사용자에게 입력을 요청해야하는 상황을 경험할 수 있습니다. QString. 나머지 폴더를 계속 스캔하기 전에 대답을 기다려야합니다. 그러나 작업자 스레드는 그것이 나온 QInputDialog를 표시 할 수 없습니다. GUI 스레드 만.
슬롯 및 신호는 Qt의 값을 반환 할 수 없기 때문에 사용할 수 없습니다. 슬롯과 참조 된 QString을 사용하여 시도했지만 가끔 충돌이 발생합니다. thread-safe는 아닙니다.
QMetaObject :: invokeMethod를 시도했지만 작동하지 못했습니다. 또한 스레드가 안전합니까?
누구나 여기에 대한 해결책이 있습니까?
아래 코드는 도움이된다면, "압축"되어 있으므로 내 변수 이름과 실제 물건에 익숙해지는 데 귀중한 시간을 낭비하지 않습니다.
초기 CODE (작업자 스레드에서 QInputDialog) MainWindow.cpp
void MainWindow::worker_create(){
Worker* worker = new Worker;
QThread* thread = new QThread;
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT (start_work()));
connect(worker, SIGNAL(worker_status_changed(QByteArray)), ChanComObject, SLOT(worker_update(QByteArray)));
connect(worker, SIGNAL(finished(QString)), this, SLOT(worker_destroy(QString)));
connect(worker, SIGNAL(finished(QString)), worker, SLOT(deleteLater()));
connect(worker, SIGNAL(finished(QString)), thread, SLOT (quit()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
Worker.cpp는
는Worker::ask(){
QStringList listToChooseFrom;
listToChooseFrom.append("A");
listToChooseFrom.append("B");
QString answer = QInputDialog::getItem(this, "Title", "Message", listToChooseFrom, 0, false, &ok);
return answer;
}
는
음흉 참조 코드 (참조 된 QString은 가끔 작동 는 다른 시간은 충돌 ) 음란 한 레퍼런스 트릭은 이것과 같았습니다. 먼저 MainWindow.cpp에서 :
작업자의 다음void MainWindow::worker_create(){
// all other stuff from above, but an extra connect:
connect(worker, SIGNAL(worker_asks(Qstring*)), SLOT(gui_thread_dialog(QString*)));
}
void MainWindow::gui_thread_dialog(*sneakyReturnValue){
QString answer = QInputDialog::getItem(this, "Title", "Message", listToChooseFrom, 0, false, &ok);
*sneakyReturnValue = answer;
}
16,..
Worker::ask(){
QString sneakyReturnValue;
emit worker_asks(*sneakyReturnValue);
return sneakyReturnValue;
}
INVOKEMETHOD 코드 내가 시도 invokeMethod (이 스레드 안전 하나 확실하지,() 부모로 인해 작업을 가져올 수 없습니다) 일 없어,하지만MainWindow.cpp
Q_INVOKABLE QString askUser();
.. 그리고에 MainWindow.cpp
에 .. 같이 갔다 결코마지막 Worker.cpp
Worker::ask(){
QString dialogReturn;
QStringList listToChooseFrom;
listToChooseFrom.append("A");
listToChooseFrom.append("B");
bool u = QMetaObject::invokeMethod(parent,
"askUser",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QString, dialogReturn),
Q_ARG(QStringList, listToChooseFrom));
if(!u){ qDebug() << "invokeMethod failed"; }
result = dialogReturn;
}
에서 5,
QString MainWindow::askUser(){
QStringList listToChooseFrom;
listToChooseFrom.append("A");
listToChooseFrom.append("B");
return QInputDialog::getItem(this, "Title", "Message", listToChooseFrom, 0, false, &ok);
}
하지만 invokeMethod의 첫 번째 인수는 GUI 스레드 작업 ..에 대한 참조를 가져올 수 없습니다. 부모가 작동하지 않습니다. 나는 내 직원이 내 GUI 스레드의 자식이 아니라고 생각한다. 음, parent()는 적어도 작동하지 않습니다.
설명에 혼란이 있기 때문에 코드를 구현하기가 어렵습니다. github 또는 유사한 방법으로 오류를 재현하는 코드를 공유 할 수 있습니다. – eyllanesc
제 질문 요약 : 스레드가 입력을 기다리는 동안 비 GUI 스레드에서 QInputDialog를 표시하는 방법은 무엇입니까? – JaredNinja
제 아이디어는 코드에 어떤 문제가 있는지 확인하는 것입니다. – eyllanesc