2017-01-30 3 views
0

私のC++プロジェクトでFLTKを実行しようとしています。私はOMNeT ++シミュレーションを作成しています。エミュレートされたホストのようなGUIを使用したいと思っています。つまり、送信ボタンを作ることができ、GUIに接続されたホストはシミュレーションで送信するメッセージを待ち行列に入れます。FLTKとC++ 11スレッドで「Tcl_ServiceModeHook:Notifier not initialized」エラーが発生しました

私が抱えている問題は、FLTKウィンドウが実行されるとウィンドウを閉じるまでシミュレーション全体がフリーズするのを待つことです。私の解決策はGUIを別のスレッドで実行することでした。しかし、今私はこのエラーが表示されます:

Tcl_ServiceModeHook: Notifier not initialized 

以下は、スレッドとGUIを含むクラスのコードです。

#include <Enumerations.H> 
#include <Fl.H> 
#include <Fl_Box.H> 
#include <Fl_Widget.H> 
#include <Fl_Window.H> 
#include <GUI.h> 


void GUI::callThread() { 
    t = std::thread(&GUI::openWindow, this); 
} 

int GUI::openWindow() { 
    Fl_Window *window = new Fl_Window(300,180); 
    Fl_Box *box = new Fl_Box(20,40,260,100,"Hello, World!"); 
    box->box(FL_UP_BOX); 
    box->labelsize(36); 
    box->labelfont(FL_BOLD+FL_ITALIC); 
    box->labeltype(FL_SHADOW_LABEL); 
    window->end(); 
    window->show(); 
    return Fl::run(); 
} 

私はそれを呼び出すために行うすべては、次のとおりです。

GUI *g = new GUI(); 
g->callThread(); 

私だけではなく直接)(openWindowを呼び出すと、ウィンドウが細かい開きますが、シミュレーションの残りの部分ではないので、それがアクションを待ち続けることができます。

私はこのクロスプラットフォーム(MacとWindowsで動作する必要があります)を作ろうとしています。私はFLTKが次善策のように思えるようにQt(設定が複雑すぎる)とwxWidgets(コンピュータ上でエラーを作る)を試みました。

このエラーを修正する方法を知っている人や、GUIを設定するためのより良い方法について意見があれば、私はすべて耳にします。これは私ができる唯一のもののように思えました。

+0

私はC++のGUIプログラミングに慣れていませんが、 toを実行することは、シミュレーション時間と実行時間が関連していないという事実を扱うことです。基本的には、OMNeT ++コードとは独立した方法でGUIスレッドを開始する必要があることを意味します。これは、プログラミングモデルが実際には予期しないものです。あなたの目標が正確であるかどうかにもよりますが、一貫性に問題があるかもしれません(シミュレーション時間がユーザーの見ているものよりも100倍遅い場合、約100倍速くなります)。 –

+0

C++からそうしようとしているようですTclはここにどのように関わっていますか? –

+0

OpenWindowは静的として宣言されていますか? – cup

答えて

0

OMNeT ++ 5.0以降にはQTベースのランタイムであるQtenvがあります(Tkenvは廃止されました)ので、QTのセットアップや依存関係などはOMNeT ++によって行われます。 QtenvはOMNeT ++ 5.1のデフォルトランタイムになります

達成しようとしていることは本当に明確ではありません。ボタンを押すたびにイベントキューにイベントを挿入するには、別のスレッドを使用する必要がありますが、シミュレーションとウォールクロックの時間がどのように関係しているかを明確にする必要があります。同期が必要な場合は、シミュレーション時間と壁掛け時間を同期させるリアルタイムスケジューラを実装する必要があります。 OMNeT ++のソケットの例はこれを行い、同様に動作しますが、イベントキューに挿入された外部イベントは、GUIから来たものではない(あなたがブラウザでアタッチできる)ソケットから来ていることを除いて説明したとおりです。

同期を気にしない場合(つまり、これを何らかのデモンストレーションに使用したい場合は、リアルタイムスケジューラを使用する必要はありませんが、OMNeT ++は本質的にシングルスレッドであり、あなたのGUIは別のスレッドで実行されているので、それらも同期させる必要があります。つまり、OMNETがGUIスレッドから使​​用しているものにアクセスすることは絶対に禁止されています(または悪いことが起こります)。

貧しい人のソリューション:イベントをトリガーするだけの場合(つまり、ボタンが本当に必要な場合)揮発性boolパラメータを定期的にポーリングするアプリケーションをホストに書き込みます。パラメータが "true"であれば、イベントを送信し、パラメータを "false"に設定します。今あなたはどのようにイベントを引き起こしますか?プロパティインスペクタ(実行時に左下のパネル)で指定されたノードのパラメータを参照し、その値を手で戻してtrueに戻し、シミュレーションを続行することができます。次のポーリングでは、ホストのアプリケーションは、パラメータが真であることを再び検出し、送信を再度行います。明らかに制限されていますが、あまりにも多くのコードを書くことなく、限られたインタラクションを提供します(そして、すべてのマルチスレッドの問題はランタイム自体で処理されます)

関連する問題