2011-01-03 10 views
0

QThreadを作成するメイン(GUI)スレッドがあります。QThreadで動作するCコードからQMessageBoxを表示

QThreadでは、私はQMessageBoxを表示する必要があるC関数を呼び出しています。これまでのところ、私は単純に以下を使用しました:C++コードでは、単純に次のように使用しました:C++コードで、このコードを呼び出しました。これはスレッドなしで正常に動作しましたが、スレッドでは別のスレッドからGUI関数を呼び出すことができないため、エラーが発生します。

通常、これはthis questionの回答のような信号を使用することで回避できます。しかし、私はCコードからこれを行うことができるとは思わない。

CコードをGUIスレッドと通信させ、QMessageBoxを表示するにはどうすればよいですか?

ありがとうございました。

P.S.

可能ならば、私は今のように、Cコードのヘッダにextern void notify(char *)宣言が単にあり、そして可能ならば、私はそれはそれに滞在したいと思います(Cのコードに触れることなく、これを行うにしたいと思います。

答えて

3

あなたがそれに次を追加することができ、あなたのGUIのためQWidgetまたはQMainWindow派生クラスを持っていると仮定すると:

ここ
class MyWidget : public QWidget 
{ 
    Q_OBJECT; 
public:  
    MyWidget() 
    { 
     connect(this, SIGNAL(notify_sig(QString)), 
       this, SLOT(notify_slot(QString)), 
       Qt::QueuedConnection); 
    } 

    void notify(QString str) 
    { 
     emit notify_sig(str); 
    } 

    signals: 
     void notify_sig(QString str); 

    slots: 
     void notify_slot(QString str) 
     { 
      QMessageBox::information(0, "", str); 
     } 
}; 

あなたがウィジェットクラスのメンバーであるパブリック関数notify()を持ってMyWidget::notify()結果を呼び出します。キューされたconnを介して自身に送信されている信号(これは、スロットがGUIスレッドで呼び出されることになります)。今すぐC notify()コールは、ウィジェット/ウィンドウのnotify()関数を呼び出すだけです。 C notify()関数で利用可能なウィジェットへのポインタを実際に持っていないので、これは難しいことがあります。

通常、Cインターフェイスではvoid*の値を渡すことができ、通知コールでその値を返します。これにより、C関数が呼び出されたときにMyWidgetへのポインタを渡してからnotify()実装のMyWidgetにキャストすることができます。

MyWidget* wid = ...; 
C_function(arg1, ..., wid); 

//... 

void notify(char* str, void* userdata) 
{ 
    MyWidget* wid = static_cast<MyWidget*>(userdata); 
    wid->notify(QString(str)); 
} 

Cインターフェイスを変更できない場合、ウィジェット/ウィンドウのポインタを取得するための何らかのグローバルな方法を使用する必要があります。

私はこのコードをテストしておらず、これを行う簡単な方法があるかもしれないことに注意してください。

+0

お返事ありがとうございます!私はあなたの答えが少し誤っていると思うか、間違って説明しましたが、 'notify'(非クラス)関数は実際にはC++コードにあります(Cコードはそれを呼び出すだけです)。 **あなたの例では 'MyWidget'へのポインタを取得します。だから、私はあなたの提案したように信号とスロットを使用する私のメインウィンドウクラスのメソッドを呼び出すことができます。しかし、とにかく、私はあなたのアプローチを使いました、それはうまくいきます(コンパイラが 'public signals'を好まなかった、それはちょうど' signals'です)。 – houbysoft

関連する問題