C++ 使用QT查看来自摄影机的流图像

C++ 使用QT查看来自摄影机的流图像,c++,linux,qt,C++,Linux,Qt,我有一个软件,通过网络将JPG发送到GUI客户端,该客户端应该显示这些图像。我基本上希望将它们显示在qt窗口中,但我对qt如何显示连续的JPG有问题。我做了一个测试,通过将图像打印到一个文件来查看是否正确获取了图像,结果很好。以下是主要代码: int main(int argc, char *argv[]) { // initialize resources, if needed // Q_INIT_RESOURCE(resfile); QApplication app

我有一个软件,通过网络将JPG发送到GUI客户端,该客户端应该显示这些图像。我基本上希望将它们显示在qt窗口中,但我对qt如何显示连续的JPG有问题。我做了一个测试,通过将图像打印到一个文件来查看是否正确获取了图像,结果很好。以下是主要代码:

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;
};
这是代码的相关部分,用于将图像绘制到无限循环内的屏幕上:

从main调用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);
while(myrvalsetPixmap(imgjpg);
我只对从文件加载的一个图像使用了这个方法,但是当我对一组流图像使用相同的方法时,这个方法不起作用。我是Qt新手,所以我肯定我犯了一个微妙的错误


非常感谢

因为您处于无限循环中,Qt可能没有机会处理事件。在设置PixMap之后,您是否可以尝试调用QCoreApplication::processEvents?

除了Mason Chang的答案之外,更好的方法是将显示屏设为插槽,然后从计时器调用插槽


setTimer值0实际上是一个循环-它在插槽完成后立即调用,但仍允许其他处理。

我建议创建一个
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
    }
};
调用将导致在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();
}

这可能不是性能最好的实现,但它很简单,可以满足您的需要。

如何循环调用
recv()
并加载映像?(你能把这两项任务分成各自的功能吗?)!这似乎就是问题所在。我会尽快试试这个。谢谢我喜欢你的设置,但是我仍然不知道我的主代码是什么样子的?它看起来像这样吗:ImageProviderIP;图像显示器id(&cw,&ip);你有完整例子的链接吗?我无法看到控制流