首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在QML插件的QGLWidget上绘制QGLWidget

在QML插件的QGLWidget上绘制QGLWidget
EN

Stack Overflow用户
提问于 2011-12-09 13:52:24
回答 2查看 5.1K关注 0票数 4

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

重要的是,我已经在没有QGLWidget的情况下完成了所有这些工作,所以我知道问题是设置和使用QGLWidget。

该插件正在以下网站注册:

代码语言:javascript
复制
qmlRegisterType<Video>(uri,1,0,"Video");

因此,Video是插件的主要类。关于它的构造函数,我们有:

代码语言:javascript
复制
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(),我不知道这是否是正确的方法,因此我想就此提出一些建议:

代码语言:javascript
复制
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;,该类的头定义为:

代码语言:javascript
复制
class GLWidget : public QGLWidget
{
    Q_OBJECT
public:        
    explicit GLWidget(QWidget* parent = NULL);
    ~GLWidget();

    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image);
};

看起来很简单。现在,QGLWidget的实现如下:

代码语言:javascript
复制
GLWidget::GLWidget(QWidget* parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
   // Should I do something here?
   // Maybe setAutoFillBackground(false); ???
}

GLWidget::~GLWidget()
{
}

最后:

代码语言:javascript
复制
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); 
}

我遗漏了什么?

我最初问过关于Qt论坛的这个问题,但没有得到任何答复。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-13 11:19:41

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

这段代码 理解如何实现这一点非常有帮助。

顺便说一句,我发现这些东西都是在view里面画的。这只是我需要执行view->show(),但这创建了另一个窗口,这不是我想要的。我上面分享的链接有答案。

票数 5
EN

Stack Overflow用户

发布于 2011-12-09 14:35:12

我认为您必须使用opengl函数来绘制glwidget。

一种可能的方法是在paintGL()方法中覆盖GLWidget,然后用glDrawPixels()绘制图像。

代码语言:javascript
复制
glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(buffer.width(), buffer.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer.bits());

其中缓冲区是一个需要使用QGLWidget::converrtToGLFormat()静态方法转换的QImage对象。

请参考以下源代码:https://github.com/nayyden/ZVector/blob/master/src/GLDebugBufferWidget.cpp

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8446437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档