[Solved] Embedding an existing GLWidget into a QML component
-
Hallo dear Qt fellows,
Recently I've started developing with QT and QML and so far I'm quite satisfied. Now I've encountered a problem though that I cannot solve on my own. At the moment I am trying to embed an existing GLWidget into a QML component. The GLWidget shows scan data in progress (via several libraries and 3rd party code) and works well on its own. I just cannot figure out how to include it into my QML UI, so that it fits well into the interface. My interface has a side bar that is made of a bezier curve and thus is to overlap the GLWidget partly. I will provide a screenshot for clarification.
!http://www7.pic-upload.de/02.08.11/yfcj5lc5sk1.jpg(Screenshot)!
As you can see, the GLWidget (with black background) ought to fit under the left side bar.
I wish there was something easy like...
@
Item {
id: glwidget
source: useMyGlwidgetFromTheCxxFiles();
}Item { width: parent.width; height: parent.height
id: leftSidebar
}
@
... or some other integration of the widget into QML or something like rendering the GLWidget onto a QML component. Just anything to make it happen :)Can anyone point me to a solution? I would be infinitely grateful.
Regards,
FranzPS: At the moment, the GLWidget is just placed on the window via a QVBoxLayout and setContentMargins. I hope there is a more beautiful solution.
-
You can't integrate a QGLWidget into QML, but you can use a QGLWidget as the viewport for the QML and render both the QML and the contents of the GLWidget into that viewport.
-
I think you are pointing at something along these lines:
@
QDeclarativeView* view = new QDeclarativeView;
QGLFormat format = QGLFormat::defaultFormat();
format.setSampleBuffers(false);
QGLWidget *glWidget = new QGLWidget(format);
glWidget->setAutoFillBackground(false);
view->setViewport(glWidget);
view->setSource(QUrl::fromLocalFile("ui/test.qml"));
@I can tweak my code to view the given *.qml. But how can I view the GLWidget in the background of the UI?
With the code above I can only see the QML UI. The same applies to the following code that implements the custom GLWidget.
@
glWidget = new GLWidget;// need a declarative view to display QML UI
QDeclarativeView* view = new QDeclarativeView;//(this);QGLFormat format = QGLFormat::defaultFormat();
// You can comment the next line if the graphical results are not acceptable
format.setSampleBuffers(false);
//QGLWidget *glWidgetx = new QGLWidget(format);
// Comment the following line if you get display problems
// (usually when the top-level element is an Item and not a Rectangle)
glWidget->setAutoFillBackground(false);
view->setViewport(glWidget);view->setSource(QUrl::fromLocalFile("ui/test.qml"));
view->setResizeMode(QDeclarativeView::SizeRootObjectToView);view->setGeometry(100,100,800,600);
//view.show();
setCentralWidget(view);
@I can only see my GLWidget (but on top, not in the background) when I attach it to a layout through addWidget like this:
@
QDeclarativeView* view = new QDeclarativeView(this);
view->setSource(QUrl::fromLocalFile("ui/test.qml"));
view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
view->setGeometry(100,100,800,600);
//view.show();
setCentralWidget(view);
glWidget = new GLWidget;
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->setContentsMargins(220, 80, 170, 0);
mainLayout->addWidget(glWidget);
centralWidget()->setLayout(mainLayout);
@I would be eternally grateful if someone could point me to a solution. I've been searching for days now and can't figure it out.
It should be like this (with | being semi-transparent or *.png overlays as visible in the picture above):
Viewer <) QML-UI | GLWidget || MainWindowand not like this:
Viewer <) GLWidget | QML-UI || MainWindow.Pleeease help.
-
Take the OpenGL rendering code from the GLWidget and put it in a QDeclarativeItem. Use this custom QDeclarativeItem in the QML.
-
[quote author="Bradley" date="1312320568"]Take the OpenGL rendering code from the GLWidget and put it in a QDeclarativeItem. Use this custom QDeclarativeItem in the QML.
[/quote]
Do you mean the code in paintGL()? What about the other code (e.g. event handling?)I think what you mean is something like this:
http://developer.qt.nokia.com/forums/viewthread/4109/I will try that as soon as possible and report how it went.
-
Still not working. I did what you told me, although I don't quite know how to use the custom item in the QML. I have implemented the linked example to have a small project with no collateral influences. There are no build or runtime errors, I just cannot see the content (except the standard rectangle). I will post my code for reference. When I change positions of MDE and Rectangle in the .qml, only white background appears.
What am I doing wrong?
Header:
@
#ifndef QWIDGETS_HPP
#define QWIDGETS_HPP#include <QDeclarativeItem>
#include <QGLWidget>class MDE : public QDeclarativeItem
{
Q_OBJECTpublic:
MDE(QDeclarativeItem *parent = 0);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
};#endif // QWIDGETS_HPP
@Source:
@
#include "GLItem.h"
#include <QApplication>
#include <QDeclarativeView>MDE::MDE(QDeclarativeItem *parent )
{
setFlag(QGraphicsItem::ItemHasNoContents, false);
}void MDE::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->beginNativePainting();
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_QUADS);
glColor3ub(0,0,255);
glVertex2d(-0.75,-0.75);
glVertex2d(-0.75,0.75);
glColor3ub(255,0,0);
glVertex2d(0.75,0.75);
glVertex2d(0.75,-0.75);
glEnd();
painter->endNativePainting();
}int main(int argc, char *argv[])
{
QApplication app(argc, argv);qmlRegisterType<MDE>("MDEPlugins", 1, 0, "MDE");
QDeclarativeView view;
QGLWidget *glWidget = new QGLWidget;
view.setViewport(glWidget);
view.setSource(QUrl::fromLocalFile("my.qml"));
view.show();
return app.exec();
}
@QML:
@
import QtQuick 1.0
import MDEPlugins 1.0Item { width: 400; height: 300
MDE { width: 300; height: 200
}
Rectangle { width: 200; height: 100
anchors.right:parent.right
color: "blue"
}}
@ -
Try this
@
void MDE::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->beginNativePainting();
glBegin(GL_QUADS);
glColor3ub(0,0,255);
glVertex2d(boundingRect().left(), boundingRect().top());
glVertex2d(boundingRect().right(), boundingRect().top());
glColor3ub(255,0,0);
glVertex2d(boundingRect().right(), boundingRect().bottom());
glVertex2d(boundingRect().left(), boundingRect().bottom());
glEnd();
painter->endNativePainting();
}
@ -
Wow, it works!! What happened? Was the GL code wrong?
Anyway, I tried it with my custom code and - after some minor fiddling - it works, too! Oh dear, I could kiss you right now :D After many hours of testing, it finally works as intended. You saved me countless hours and made a sweet sweet UI possible.
THANK YOU!
-
Yes, the GL code was wrong. It was clearing the buffer and it was assuming a different coordinate system. I removed the calls to glClear and glIdentity and changed the vertices.