2011-06-28 24 views
0

私は、ネットワーク経由でJPGをそれらのイメージを表示するはずのGUIクライアントに送信するソフトウェアを持っています。基本的にqtウィンドウに表示したいのですが、qtが連続JPGを表示する方法に問題があります。私はファイルに印刷してイメージを正しく取得しているかどうかを確認するためのテストを行いました。ここでの主なコードは次のとおりQTを使用してカメラからのストリーミングイメージを表示する

int main(int argc, char *argv[]) { 
    // initialize resources, if needed 
    // Q_INIT_RESOURCE(resfile); 

    QApplication app(argc, argv); 
    CameraWindow cw; 
    cw.show(); 
    //app.setActiveWindow(&cw); 
    cw.getData();  // this paints the window 
    return app.exec(); 
} 

ここでウィジェットを初期化するコードは次のとおり

class CameraWindow : public QDialog { 
    Q_OBJECT 
    public: 
    bool serverConnected; 
    void getData(); 
    CameraWindow() 
    { 
     imgl = new QLabel; 
     widget.scrollImage->setWidget(imgl); 
     widget.scrollImage->setBackgroundRole(QPalette::Dark); 
    } 
    QLabel *imgl; 
    virtual ~CameraWindow(); 
    private: 
    Ui::CameraWindow widget; 
}; 

これは無限の内側にある画面に画像をペイントすることになっているコードの要部でありますループ:メインから呼び出さ

のgetData():

while (myrval < Header.imageSize) { 
    myrval = myrval + recv(msgsock, (char*) ((int) buff + myrval), 
     Header.imageSize- myrval, 0); 
} 

//buff contains the jpg at this point 
QPixmap imgjpg; 
imgjpg.loadFromData((const unsigned char*)buff, Header.imageSize, "JPG"); 
//scroll image is the parent that displays child 
//in this case, the label 
imgl->setPixmap(imgjpg); 

私はこれがために働くようになりましたファイルからロードされた画像は1つだけですが、ストリーミングイメージのセットに対して同じメソッドを使用すると、これは機能しません。私はQtが新しく、微妙な間違いがあると確信しています。

多くの感謝!

+0

あなたの 'recv()'呼び出しをどのようにループしてイメージをロードしていますか? (これら2つのタスクを別々の機能に分けることができますか?) – sarnold

答えて

1

あなたは無限ループのため、Qtはイベントを処理する機会がないかもしれません。 setPixmapの後にQCoreApplication :: processEventsを呼び出せますか?

+0

ああ興味深い!それは問題のようです。私はできるだけ早くこれを試みます。ありがとう! – roboto1986

0

メイソンチャンの答えに加えて、これを行うためのよりよい方法は、ディスプレイをスロットにしてからタイマーからスロットを呼び出すことです。

setTimerの値0は効果的にループです。スロットが終了するとすぐに呼び出されますが、他の処理は可能です。

1

私はそれが画像の準備ができていることを他の人に警告ImageProviderクラスを作成することをお勧めしたい:

public class ImageProvider : QObject { 
    Q_OBJECT 
public: 
    QPixmap getCurrentImage() const { /* retrieve current image */ } 
signals: 
    void newImageAvailable(); 
}; 

今、あなたはそれを表示するためにクラスが必要なので、のはImageDisplayerことを呼び出していることを前提としてもらおうラベルは、あなたの現在の画像がそれに設定したことimageLabelと呼ばれています:

public class ImageDisplayer : QWidget { 
    Q_OBJECT 
    QLabel *imageLabel; 
    ImageProvider *provider; 
public: 
    ImageDisplayer(QWidget *parent, ImageProvider *imageProvider) { 
     this->imageLabel = /* setup QPixmap */; 
     this->imageProvider = imageProvider; 
     connect(imageProvider, SIGNAL("newImageAvailable()"), SLOT("setNewImage()")); 
    } 
    public void setNewImage() { 
     imageLabel->setPixmap(imageProvider->getCurrentImage()); 
     update(); // schedule the repaint 
    } 
}; 

updateの呼び出しが再描画とすぐQtは合理的と判断すると発生する原因となります。これにより、スキップされたフレームや他のもの(これは望ましくないかもしれません)も可能になります。

最後に、あなたはすべてがあなたのメインウィジェットによって接続されますことを確認したいと思う:

public class MainWidget : QMainWindow { 
    Q_OBJECT 
    ImageDisplayer *imageDisplayer; 
    ImageProvider *imageProvider; 
public: 
    void MainWidget() { 
     this->imageProvider = new ImageProvider(/*your dependencies*/); 
     this->imageDisplayer = new ImageDisplayer(this, imageProvider); 
    } 
} 

そしてメインで:

int main(int argc, char* argv[]) { 
    QApplication app(argc, argv); 
    MainWidget w; 
    w.show(); 
    return app.exec(); 
} 

この可能性が最も行っ実装ではありません、しかし、それは簡単で、あなたのニーズに応えるかもしれません。

+0

あなたの設定が気に入っていますが、私の主なコードはどのように見えるのですか? これは次のようになりますか? ImageProvider ip; ImageDisplayer id(&cw、&ip); 完全な例へのリンクがありますか?コントロールフローがわかりません。 – roboto1986

関連する問題