2010-11-24 8 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

これはあなたが持っているようなものではありませんが、少しでも作業が可能です。 1つのオプションはもちろん、クラスをQObjectに変換することです。その時点で信号を送信できます。しかし、exec中の遅延のためには役に立ちません。それが必要な場合は、メインのUIスレッドに存在するが他のスレッドから呼び出すことができるメッセージングクラスを持つことができます。他のスレッドから呼び出された関数は、セマフォをロックし、セマフォを作成し、セマフォとメッセージを表示してそれ自身にイベントを送信する必要があります。次に、customEvent(UIスレッド内にあります)で、メッセージボックスを作成し、execし、メッセージボックスがクリアされた後にセマフォをトリガーします。

もちろん、情報を別の方法で送信する必要がある場合は、もう少し複雑になります。次に、私がここで説明するような基本的なクラスではなく、プログラムの完全なサブシステムが必要になります。

+0

私は「片道」の場合があると思う(質問の私の編集を参照)。それはあなたが意味することですか?明示的なロックはしませんが、うまくいくようですか?情報を送り返す方法の例がありますか? –

+0

私はあなたのコードを完全には検証しませんでしたが、このアプローチはうまくいくかもしれません。 DialogHandlerが(メインの例で行ったように)UIスレッドでインスタンス化されていることを確認する必要があります。私は特に便利な例はありませんが、元のオブジェクトに戻ってカスタムイベントを介して情報を送信することができます。 –

+0

これは動作していると思っていましたが、ループを初めて初めて実行するように見えて、プログラムが停止しているようです(プロセッサは0%ですが、2回目の繰り返しは実行しません)。 http://codepad.org/KoyJBU6C - メッセージボックスが3回連続して表示されると思います。しかし、それは一度しか表示されません、そして、私が言及したこの「失速」を行います。なぜそれが起こるかもしれないかについての考えはありますか? –

関連する問題