Fails to paint within QGLWidget - qt

I have a weird issue with OpenGL in Qt. I have a derived class from QGLWidget. I use makeCurrent() in initializeGL because I need to call some OpenGL functions first. The OpenGL widget is embedded into a QFrame.
When I run the application in QtCreator, it perfectly runs. When I run it as a standalone one, the OpenGL surface seems not to update at all.
Any clue?
EDIT: the problem seems to come with optirun…

Related

QT designer implementation error

Actually i activated the Qt creator from terminal ex: in Linux sudo Qt-creator.sh. so qt application opens.when i tried to design the UI by drag and dropping the buttons , widgets to form a type of UI.when i run the application , it just show the blank widget. the designed part done in UI is not implemented. so whatever changes done in UI designer, is not displaying when i run application. i don't no where is the issue. is it because of activating the qt from terminal.
the reason for activating qt creator from terminal because, i need to cross compile the binary code for Arm-Cortex controller. so i need to follow the steps for setting compiler for arm-cortex in qt application.however the cross compilation works. but if any changes done on qt designer, when i run the application , i cant able to see the changes in UI output window.
Let me start by providing some background.
The Qt library allows you to create graphical user interfaces (GUI) using two alternative methods:
QWidgets
Qt Quick
QWidgets uses a set of widgets written in C++ that you can either create and layout yourself using explicit C++ code, i.e. manually, or use Qt Designer to edit the interface of your applicaiton in a WYSWIG style, producing a .ui. file that you use in a certain way later on.
Qt Quick uses a declarative approach to creation of the user interfaces, with a special markup language similar to HMTL. We're not discussing it here as it's not the approach that you're using.
Now let's take a closer look at how Qt Designer works in conjunction with .ui. files, given that our application is written in C+.
Once you launch Qt Designer and edit a form, then save it, a .ui. file is produced. It's an XML file containing an hierarchical description of the UI you've created. However, to be able to use that form as the GUI of your application, additional steps are required. You need to "tell" the application to use this .ui. file. This is done as follows. A special executable, the UI compiler uic, is invoked (automatically via qmake or cmake) to process the .ui file, and generate C++ code in form of a header file. You then include the header file in the file that includes your application code, and use one of the three available methods to create the UI of your application using the generated code.
The simplest method is shown below.
class MyForm : public QWidget
{
Q_OBJECT
public:
MyForm(QWidget *parent = 0);
private:
Ui::MyForm ui;
};
The ui member object is an object of the class generated by uic - the UI compiler mentioned above. The class contains code for creating the user interface, organizing it into a layout, and managing it throughout the application lifetime.
Then, in the .cpp file, we have the constructor:
MyForm::MyForm(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
The important call here is ui.setupUi(this). This creates the UI elements, applies the layout, and sets the layout on the widget provided as the argument to this call. Remember, our class inherits from QWidget.
The other approaches include inheriting from the generated class and dynamically loading the .ui file, omitting the compilation by uic, using the QUiLoader class. Please consult http://doc.qt.io/qt-5/designer-using-a-ui-file.html for further reference.
As far as starting Qt Designer from terminal, it has no effect on the problem. Moreover, starting a GUI application as root is highly discouraged on Linux, as it poses a major security issue.

Benefits of using QOpenGLWidget over normal QWidget

Since Qt 5.4 version, the QOpenGLWidget was introduced to enable the OpenGL rendering capabilities.
Apart of calling OpenGL APIs, QOpenGLWidget can also be used as a normal QWidget, in which QPainter is used.
So I'm wondering, if I don't plan to directly call any OpenGL API to render my widget, but only QPainter APIs, is there still any (performance perhaps) benefits of using QOpenGLWidget instead of QWidget?
QOpenGLWidget, when directly painted on using QPainter, does all the painting using OpenGL - that's one of its two main purposes. Using QPainter on a QOpenGLWidget has Qt doing the legwork of translating the painter API into GL state setup and draw calls. If you have some OpenGL background and use a debug build of Qt, you can trace into the source and see how Qt translates your calls, so that you can issue your painter calls in a way that efficiently maps to OpenGL. State changes are expensive, so make sure you batch the operations that use the same pen/brush etc. The painting is done by the QOpenGL2PaintEngineEx.

How to save image of application containing QGLWidget

I am looking for some example code that I can use to save an image of my Qt application. The application is a QMainWindow that contains a QGLWidget. I want to be able to screen capture all the GUIs (including the QGLWidget rendering) but have not been able to find any example code for this.
What I've tried:
QPixmap pixmap = QPixMap::grabWidget(QApplication::activeWindow);
pixmap.save(QString("test.png"));
This only save the GUIs but leaves a black background around the QGLWidget.
Anyone know of a technique for doing this in Qt 4.8.4?
Thanks,

QGLWidget for graphics and QT for GUI

I am trying to implement a custom OpenGL scene (wrapped in a QGLWidget), but still use QT controls (such as slide bars and buttons). I tried to make my main widget a QGLWidget, which has QWidgets as children. The child widgets seem to work (when I click a pulldown menu, its options appear), but the widget fails to draw (I see a white square). I changed the base class of my children widgets from QWidget to QGLWidget, and now QPainter calls work, but QT GUI stuff is still not displaying...
Some claim that a QGLWidget can not have QWidgets as children... I am not sure about that and I'm not willing to give up. By the way, I am using Visualization Library to draw the OpenGL scene, but it is just an OpenGL wrapper...
Any clues where the problem might be? Also, key events stop being processed for some reason when I add subwidgets to the GQLWidget.
Update:
I tried various combinations of widgets and layouts. It seems that the QGLWidget just gets drawn on top of anything. I even tried with raise() to arrange Z-depth of the widgets, to no avail. Is overlayGL() the only way to draw on top of an OpenGL widget?
Update 2
After months of trying, I figured out it is something related to QT. Whenever a QGLWidget is drawn on top of another QGLWidget, the first's background() function is not called. So a button is there and can be clicked, but it's not drawn. My workaround was to draw everything myself using QPainter - that works. What I found curious is, one has to use QPainter::startNativePainting() in order to draw with it. One would expect that they would overload start() in QPainter to call startNativePainting() whenever a QGLWidget is the painting device...
Another (maybe useful) fact is that QPainter calls CHANGE the Opengl context. So if you have another tool in cooperation with QPainter (in my case Visualization Library), chances are that one of them will crash (in my case VL which checks if the context state has been cleared before each frame).
There is a labs example of rendering Qt widgets using opengl it's a little old and I haven't tried it with the improved qglwidget in 4.8
There is also an issue with drawing over the top of a fullscreen QGLwidget - it was supposedly a bug in NVidia's openGL driver. It doesn't seem to have been resolved
https://bugreports.qt-project.org/browse/QTBUG-7556
If I were you I would use the QGLWidget as a viewport for a QGraphicsScene, then you can draw your widgets using a QGraphicsProxyWidget. That way you get a proper OpenGL viewport with the ability to put widgets in and manipulate them easily.
Did u try to call update() explicitly? I find that sometimes QGLWidget update the display stuff kind of slow.
This is an old question, but I recently had quite a bit of trouble with this, and this is what helped me -
Use QML/QT Quick. QML is a javascript-like language that allows you to layout your widget elements on a window and do basic processing on events like mouse clicks. There are a few other cool features, but the one that is most relevant to this question is that you can import qt widgets from C++ code.
So you can make a custom QGLWidget, import it into the QML window, and set the size/position/stick widgets on top of it in whatever you want, very easily. QT's Scenegraph example does a great job explaining this. Scenegraph's code is also included as an example in at least Qt Creator 3.2.1 Open Source (that's the version I have anyway)

Is it possible to declare a QWidget as a child of a window created outside of Qt?

I'd like to use Qt in my browser plugin, but I don't get to create my own window, the browser does.
What I'd like to do is create a QWidget as a child of a native window handle... Is this possible?
You may be able to take over a native window handle by calling QWidget::create() in your custom widget's constructor. Note that it's a protected method so you can't call it on a normal QWidget.
If you're using a dialog and not an embedded window it's relatively easy. Call QWidget::winId() on your top-level widget. In Qt4 this will return a WId, which is a preprocessor definition for HWND. In Qt5, WId is a typedef for HWND, so you have to perform an explicit cast:
HWND hwnd = (HWND)widget->winId()
Unfortunately, the functionality in Qt5 is currently unreliable/partially broken. As of Qt 5.4.1, it's not resolved and there's a note in the source that QWidget::winId() is "going away". note that this issue primarily affects embedded native windows in a Qt app, not vice versa. Your mileage may be better.
Note: QWidget::create() is intended for embedding native windows in Qt. It probably does not apply in your situation.
Only if you can cast it as a QWidget.

Resources