我正在尝试编写一个 QML插件,它从视频中读取帧(使用自定义小部件来执行该任务,而不是QtMultimedia / Phonon),并且每个帧都转换为{{ 1}} RGB888,然后显示在QImage
上(出于性能原因)。现在没有任何东西被画到屏幕上,屏幕一直保持白色。
重要的是要说明我已经在没有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()
作为参数时调用canvas.paint()
,我不知道是否这是正确的方法,所以我想就此提出一些建议:
QImage
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()
{
}
我错过了什么?
我最初问this question on Qt Forum但没有回复。
答案 0 :(得分:5)
<强>解决即可。问题是当我应该从加载它的应用程序中检索GL上下文时,我试图在我的插件中创建一个新的GL上下文。
This code非常有帮助了解如何实现这一目标。
顺便说一下,我发现这些东西是在view
内画的。只是我需要执行view->show()
,但这创建了另一个窗口,这不是我想要的。我上面分享的链接有答案。
答案 1 :(得分:0)
我认为你必须使用opengl函数在你的glwidget上画画。
一种可能的方法是覆盖GLWidget中的paintGL()方法 然后使用glDrawPixels()绘制图像。
glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(buffer.width(), buffer.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer.bits());
其中buffer是需要使用QGLWidget :: converrtToGLFormat()静态方法转换的QImage对象。
查看此来源以供参考: https://github.com/nayyden/ZVector/blob/master/src/GLDebugBufferWidget.cpp