Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在QML插件的QGLWidget上呈现QImage_C++_Qt_Opengl_Qt4_Qml - Fatal编程技术网

C++ 在QML插件的QGLWidget上呈现QImage

C++ 在QML插件的QGLWidget上呈现QImage,c++,qt,opengl,qt4,qml,C++,Qt,Opengl,Qt4,Qml,我正在尝试编写一个QML插件,从视频中读取帧(使用自定义小部件来完成该任务,而不是使用qtmedia/Phonon),每个帧都转换为QImageRGB888,然后显示在QGLWidget(出于性能原因)。现在屏幕上没有任何东西,屏幕一直保持白色 必须指出的是,我已经在没有QGLWidget的情况下完成了所有这些工作,因此我知道问题在于如何设置和利用QGLWidget 该插件正在以下位置注册: qmlRegisterType<Video>(uri,1,0,"Video"

我正在尝试编写一个QML插件,从视频中读取帧(使用自定义小部件来完成该任务,而不是使用qtmedia/Phonon),每个帧都转换为
QImage
RGB888,然后显示在
QGLWidget
(出于性能原因)。现在屏幕上没有任何东西,屏幕一直保持白色

必须指出的是,我已经在没有
QGLWidget
的情况下完成了所有这些工作,因此我知道问题在于如何设置和利用QGLWidget

该插件正在以下位置注册:

qmlRegisterType<Video>(uri,1,0,"Video");
因此,
Video
是插件的主要类。在它的构造函数上,我们有:

Video::Video(QDeclarativeItem* parent)
: QDeclarativeItem(parent), d_ptr(new VideoPrivate(this))
{    
    setFlag(QGraphicsItem::ItemHasNoContents, false);            

    Q_D(Video);
    QDeclarativeView* view = new QDeclarativeView;
    view->setViewport(&d->canvas()); // canvas() returns a reference to my custom OpenGL Widget
}
在我跳转到
canvas
对象之前,让我说我重载了
Video::paint()
,因此它在将
QImage
作为参数传递时调用了
canvas.paint()
,我不知道这是否是正确的方法,因此我希望得到一些建议:

void Video::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(widget);
    Q_UNUSED(option);

    Q_D(Video);
    // I know for sure at this point "d->image()" is valid, but I'm hiding the code for clarity
    d->canvas().paint(painter, option, d->image());
}
canvas
对象被声明为
GLWidget canvas并且该类的标题定义为:

class GLWidget : public QGLWidget
{
    Q_OBJECT
public:        
    explicit GLWidget(QWidget* parent = NULL);
    ~GLWidget();

    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image);
};
看起来很简单。现在,
QGLWidget
的实现如下:

GLWidget::GLWidget(QWidget* parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
   // Should I do something here?
   // Maybe setAutoFillBackground(false); ???
}

GLWidget::~GLWidget()
{
}
最后:

void GLWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image)
{
   // I ignore painter because it comes from Video, so I create a new one:
   QPainter gl_painter(this);


   // Perform drawing as Qt::KeepAspectRatio

   gl_painter.fillRect(QRectF(QPoint(0, 0), QSize(this->width(), this->height())), Qt::black);

   QImage scaled_img = image->scaled(QSize(this->width(), this->height()), _ar, Qt::FastTransformation);

   gl_painter.drawImage(qRound(this->width()/2)  - qRound(scaled_img.size().width()/2),
                        qRound(this->height()/2) - qRound(scaled_img.size().height()/2),
                        scaled_img); 
}
我错过了什么


我最初问过,但没有得到答复。

我认为您必须使用opengl函数在glwidget上绘图

一种可能的方法是重写GLWidget中的paintGL()方法 然后使用glDrawPixels()绘制图像

其中buffer是需要使用QGLWidget::converrtToGLFormat()静态方法转换的QImage对象

请查看此来源以供参考:

已解决。问题是,当我应该从加载它的应用程序检索GL上下文时,我试图在插件中创建一个新的GL上下文

非常有助于理解如何做到这一点


顺便说一下,我发现这些东西正在
视图中绘制。只是我需要执行
view->show()
,但这创建了另一个窗口,这不是我想要的。我在上面共享的链接有答案。

出于某种原因,
GLWidget::paintGL()
没有被调用,即使我在
Video::paint()
上更改,以便它执行
d->canvas().update();d->canvas().repaint()我可能会给出一个愚蠢的建议,就是在GLWidget中添加一个新的公共方法,并在该方法中调用paintGL()和updateGL(),但是当你想调用它时,你必须键入cast画布。我真的不想直接使用OpenGL调用,这就是为什么我没有像
paintGL()那样重载GL方法
。如果您仍感兴趣,此问题已解决。如果你愿意,你可以检查我的答案。你还有来源吗?我目前面临着一个类似的问题,链接转到404。我会尝试粘贴在这里,当我可以。死链接。也是新的。这条线已经快9年了。最初发布引用代码的存储库已经死了,而且早已不复存在。这是我最后一次在互联网上查找类似的源代码以供参考。从现在开始祝你好运。
glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(buffer.width(), buffer.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer.bits());