2011-06-28 79 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); 

我得到這個爲工作只是一個從文件加載的圖像,但是當我對一組流式圖像使用相同的方法時,這不起作用。我是Qt新手,所以我確信我有一個微妙的錯誤。

非常感謝!

+0

你是如何繞過你的'recv()'調用並加載圖像的? (你可以將這兩項任務分解爲各自的功能嗎?) – sarnold

回答

1

因爲你處於一個無限循環中,Qt可能沒有機會處理事件。你可以嘗試在setPixmap之後調用QCoreApplication :: processEvents嗎?

+0

啊!有趣!這似乎是問題所在。我會盡快嘗試。謝謝! – roboto1986

0

除了梅森張的答案 - 更好的方法是將顯示器作爲一個插槽,然後從計時器調用插槽。

0的setTimer值實際上是一個循環 - 只要槽完成就會回想,但仍允許進行其他處理。

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