2016-11-15 6 views
1

私はGUIを表示し、パイプからの入力を受け入れる小さなアプリケーションを作成するためにQtを使用しています。パイプを読み込むコールをブロックする

パイプが作成されていない場合

か、私は理解してそこには作家いない場合は、)、fopenブロックへの呼び出し、さらにはそれはたぶんshow()関数の後に呼ばれています考えて、UIは表示されません。

UIを表示するにはどうすればfopenとその関連コードを呼び出すことができますか?私は窓があらかじめスクリーンにある限り、fopenブロックするかどうか気にしない。

私はconnect(this, SIGNAL(window_loaded), this, SLOT(setupListener()));のようなものを使用しようとしましたが、動作は変わりません。

ヒントありがとう!

main.cppに

#include <QApplication> 

#include "metadataWindow.h" 

#include <sys/time.h> 
#include <sys/types.h> 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    metadataWindow window; 
    window.showFullScreen(); 
    window.setupListener(); 

    return app.exec(); 
} 

metadataWindow.cpp

metadataWindow::metadataWindow(QWidget *parent) : QWidget(parent) 
{ 
    this->setupUI(); // not shown here, but just basic QLabel stuff 
} 

void metadataWindow::setupListener() 
{ 
    const char *metadata_file = "/tmp/my-pipe-file"; 

    // vvvvv This here is blocking vvvvvv 
    FILE *fd = fopen(metadata_file, "r"); 

    pipe = new QTextStream(fd); 

    streamReader = new QSocketNotifier(fileno(fd), QSocketNotifier::Read, qApp); 
    QObject::connect(streamReader, SIGNAL(activated(int)), this, SLOT(onData())); 
    streamReader->setEnabled(true); 
} 

答えて

2

Xが非同期メッセージベースのプロトコルです。 Xディスプレイ・サーバーとXクライアント・プログラムは常にメッセージを交換しています。 Xクライアントプログラムは、何らかの仮想ボタンを押してウィンドウを描画し、ウィンドウ上の何かを変更したいときまで、それを呼び出します。ディスプレイサーバとクライアントプログラムとの間で交換されるメッセージがないのは、ディスプレイ上で何も起こらないときだけである。マウスポインタの移動はありません。表示操作はまったくありません。

ウィンドウを表示するタスクには、複数のステップが順番に含まれます。実際のウィンドウオブジェクト自体が作成されます。すべてのサブウィンドウが作成されます。すべてのウィンドウがマップされます。ウィンドウをマッピングすることにより、Xサーバは一連の露出イベントをクライアントプログラムに送信し、それに応じてクライアントプログラムがウィンドウの露出部分をレンダリングすることになる。すべてこれは、Xディスプレイ・サーバーとXクライアント・プログラムとの間で交換される数百のメッセージのシーケンスとして行われます。

これは、QApplication::exec()コールの機能です。 Qtのメインイベントループに入り、QtライブラリはX表示イベントをそれに応じて処理します。イベントループが実行されるまで、目に見える表示の変更はありません。

X/Qtなどのイベントベースのインフラストラクチャで作業する場合の正しいデザインパターンは、イベントベースのアプローチでもあります。あなたには2つの基本的なオプションがあります。

  1. 独立してQtのイベントループに入り、メインの実行スレッドの、新しいスレッドでのブロッキングアプリケーションロジックを実行します。これは、イベントドリブンのデザインパターンに準拠する必要性を回避し、側立っており、Qtを煩わせることなく、普通のプログラムがやることを可能にします。

  2. 独自のコードに対しても、非ブロックファイル記述子を使用したイベントドリブンモデルを使用します。 fopen()ライブラリ呼び出しは使用できません。代わりに、非ブロックモードでパイプがopen()になり、ファイルシステムパイプのもう一方のサイドが開かれると、パイプは書き込み用に選択可能になります。詳細については、open()およびpoll()のマニュアルページを参照してください。最後に、QSocketNotifierクラスのQtのドキュメントを読んでください。Qtライブラリには、メインイベントループの一部として独自のファイルディスクリプタのイベントを監視し、読み書きのタスクを処理するためのコードを呼び出す方法についても説明しています。

もちろん、実行スレッドとソケット通知プログラムの両方を使用するハイブリッドアプローチも可能です。重要な点は、プロセスがどのように正しく動作するかを理解し、Qtのメインイベントループをブロックするコードを書くことがないことです。

+0

ご清聴ありがとうございました。私は非ブロックモードで 'open()'を使って2番目のルートに行きました。その結果、 'onData()'の最初の呼び出しで 'QTextStream'パイプを初期化しました(' 'FILE * open() 'を直接実行します)。これは実際にうまく動作している、私はそれが何か欠点を持つとは思わない.. – tchap

関連する問題