2011-08-05 7 views
2

私はユーザー入力が のstd :: getline()(whileループ)でコンソールアプリケーションを作成しています。私もQextSerialPort(QIODeviceを継承)を使用しています。したがって、私はQCoreApplicationを使用し、a.exec()を呼び出すためにイベントループが必要です。Qtコンソールアプリケーション:whileループはイベントループをブロックします

問題はgetl​​ine()がイベントループをブロックし、ブロックされている間にシリアルポートから何も受信できないという問題です。 while(1){getline()}ループで

QCoreApplication :: processEvents()を使用しようとしましたが、それは良い解決策ではないことがわかりました。その後、QThreadで

QCoreApplication :: processEvents()を呼び出そうとしましたが、 が機能しませんでした。ここで

コードImが使用しています:

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    Base *base = new Base(); 
    Commander *commander = new Commander(base); 

    QObject::connect(commander, SIGNAL(end()), &a, SLOT(quit())); 
    QTimer::singleShot(0, commander, SLOT(run())); 

    return a.exec(); 
} 

void Commander::askToConnect() 
{ 
    if(base->connect() == false){ 
     cout << "Failed to open port." << endl; 
    } 
} 

void Commander::run{ 
    string inputline; 

    askToConnect(); 

    while(1){ 
     QCoreApplication::processEvents(); // ??? 

     cout << endl << "> "; 
     getline(cin, inputline); 

     // ... 
    } 
} 

がどのようにgetlineの()(または類似の方法)を持つことができるイベントループを遮断せず?

答えて

5

はい、私はメインスレッドから呼び出されたProcessEvent()メソッドで同様の経験を得ています。問題は、それが現在の呼び出しスタックの上に置かれており、無限の呼び出し深度や再入場の問題のような厄介な副作用があることです。

クリーンなソリューションを作成するために、アプリケーションにスレッドを追加するだけです。 getLine()は(コンソール)ユーザーインターフェイスに属しているので、メインスレッドに保持し、ネットワークコードを余分なスレッドに移動しますが、他のソリューションも可能です(すべての種類の相互作用のスレッドを生成し、メインスレッド)。

+0

通信コードを別のスレッドに移動することは、大抵の場合、良い考えです。シグナル/スロット接続を介してのみメインスレッドと通信できるようにすると、スレッドセーフティが無料になります。 – grefab

+0

QextSerialPortからreadyRead信号を使って非同期的にデータを受信して​​います。シリアルポートからデータを受け取ると、qDebug()でターミナルにそれを表示します。しかし、いったんイベントループがブロックされると、何かを入力してEnter(getline())を押すと、それが印刷されます。これは、whileループでQCoreApplication :: processEvents()を呼び出すためです。 – msr

関連する問題