2010-11-24 5 views
3

QObject 클래스 외부에서 메시지 상자를 표시하고 결과를 얻으려고합니다. 나는이 같은 대화 상자가 생성 할 수있을 것 :QObject 외부에서 QMessageBox 결과 표시 및 가져 오기

#include <iostream> 

#include <QApplication> 
#include <QtConcurrentRun> 
#include <QMessageBox> 

class DialogHandler : public QObject 
{ 
Q_OBJECT 

signals: 
    void MySignal(int* returnValue); 

public: 
    DialogHandler() 
    { 
    connect(this, SIGNAL(MySignal(int*)), this, SLOT(MySlot(int*)), Qt::BlockingQueuedConnection); 
    } 

    void EmitSignal(int* returnValue) 
    { 
    emit MySignal(returnValue); 
    } 

public slots: 
    void MySlot(int* returnValue) 
    { 
    std::cout << "input: " << *returnValue << std::endl; 
    QMessageBox* dialog = new QMessageBox; 
    dialog->addButton(QMessageBox::Yes); 
    dialog->addButton(QMessageBox::No); 
    dialog->setText("Test Text"); 
    dialog->exec(); 
    int result = dialog->result(); 
    if(result == QMessageBox::Yes) 
    { 
     *returnValue = 1; 
    } 
    else 
    { 
     *returnValue = 0; 
    } 
    } 
}; 

#include "main.moc" // For CMake's automoc 

void MyFunction(DialogHandler* dialogHandler) 
{ 
    int returnValue = -1; 
    dialogHandler->EmitSignal(&returnValue); 

    std::cout << "returnValue: " << returnValue << std::endl; 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    DialogHandler* dialogHandler = new DialogHandler; 

    QtConcurrent::run(MyFunction, dialogHandler); 

    std::cout << "End" << std::endl; 
    return app.exec(); 
} 
:

#include <iostream> 

#include <QApplication> 
#include <QtConcurrentRun> 
#include <QMessageBox> 

class DialogHandler : public QObject 
{ 
Q_OBJECT 

signals: 
    void MySignal(); 

public: 
    DialogHandler() 
    { 
    connect(this, SIGNAL(MySignal()), this, SLOT(MySlot())); 
    } 

    void EmitSignal() 
    { 
    emit MySignal(); 
    } 

public slots: 
    void MySlot() 
    { 
    QMessageBox* dialog = new QMessageBox; 
    dialog->setText("Test Text"); 
    dialog->exec(); 
    int result = dialog->result(); 
    if(result) 
    { 
     std::cout << "ok" << std::endl; 
    } 
    else 
    { 
     std::cout << "invalid" << std::endl; 
    } 
    } 
}; 

#include "main.moc" // For CMake's automoc 

void MyFunction(DialogHandler* dialogHandler) 
{ 
    dialogHandler->EmitSignal(); 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    DialogHandler* dialogHandler = new DialogHandler; 

    MyFunction(dialogHandler); 

    return app.exec(); 
} 

다시의 MyFunction의 결과를 얻기를,이 같은 결과를 채우기 위해 간단하게 할 객체를 전달하는 작동하는 것 같다

그게 합리적으로 보입니까? 그것을 할 수있는 더 좋은 방법이 있습니까?

+0

그래서 다중 스레드를 사용하고 있습니까? 슬롯에 msgbox를 표시하는 것 외에는 아무것도하지 않고 MyClass에 QObject 파생 클래스를 만들거나 다른 스레드의 객체를 위젯에 연결하고 거기에 메시지 상자를 표시 할 수 있습니다. –

+0

아, 맞아, 나는 그것을 QObject 클래스에 포함시키지 않았다고 생각했지만 분명히 그 클래스가 같은 스레드에 있지 않기 때문에 그것이 옳다. 나는 아직도 여기에 있기 때문에 신호와 슬롯을 연결하는 방법을 모른다. Form :: MyClass :: MyFunction() { ... 기능하는 중 ... ... 오류가 발생합니다. .. ProduceMessageBox() } MyClass는 QObject가 아니기 때문에 신호를 낼 수 없으므로 Form의 함수를 호출하려면 어떻게해야합니까? –

답변

1

당신이 가지고있는 것처럼 불가능하지만, 약간의 작업만으로도 가능합니다. 한 가지 옵션은 클래스를 QObject로 변환하는 것입니다.이 시점에서 신호를 보낼 수 있습니다. 그러나 임원 중 지연에 도움이되지 않습니다. 필요한 경우 메인 UI 스레드에 있지만 다른 스레드에서 호출 할 수있는 메시징 클래스를 가질 수 있습니다. 다른 스레드에서 호출 된 함수는 잠글 필요가 있고, 세마포어를 만들고, 표시 할 세마포어와 메시지를 사용하여 자체적으로 이벤트를 전송해야합니다. 그런 다음 customEvent (UI 스레드에 있음)에서 메시지 상자를 만들고 exec하고 메시지 상자가 지워진 후 세마포를 트리거합니다.

물론 정보를 다른 방식으로 보내야하는 경우 상황이 좀 더 복잡해집니다. 그런 다음 여기서 설명하는 것처럼 하나의 기본 클래스 대신 전체 서브 시스템이 필요합니다.

+0

"편도"사례가 있다고 생각합니다 (질문에서 편집을 참조하십시오). 그게 당신이 의미 한 것입니까? 명시 적 잠금을 수행하지는 않지만 작동하는 것 같습니다. 정보를 다시 보내는 방법의 예가 있습니까? –

+0

코드를 완전히 검증하지는 않았지만 접근 방식이 효과가있었습니다. DialogHandler가 UI 스레드에서 인스턴스화되었는지 확인해야합니다 (예제 main에서했던 것처럼). 정보를 보내면 커스텀 이벤트를 통해 원래의 객체로 되돌릴 수 있습니다. 특별한 예제는 없지만 말입니다. –

+0

나는 이것이 작동하고 있다고 생각했지만 루프를 통해 처음으로 작동하는 것처럼 보였다가 프로그램이 멈춘 것처럼 보였다 (프로세서는 0 % 였지만 두 번째 반복을 실행하지 않음)? http://codepad.org/KoyJBU6C - 메시지 상자가 3 번 연속해서 표시 될 것으로 예상됩니다. 그러나, 그것은 한 번만 보여 주며, 내가 언급 한이 "실속"을합니다. 왜 그런 일이 생길지에 대한 생각? –

관련 문제