Cut a QGLWidget? - qt

Is it possible to cut a QGLWidget? I mean I would like to cut it so i get access to the gui below. It sounds strange, but it would be a lot of work for me to divide my QGLWidget into two. I hope you understand what I mean.

I don't fully understand what you mean by "cut" and GUI below. In Qt with layout mechanisms properly used a widget consumes the area it covers and there are no widgets beneath it.
Do you want to render multiple views into a single QGLWidget? This is easily achieved by proper use of glViewport + glScissor.
EDIT due to comment
There are two kinds of windows:
Top level (those you can freely move around on the screen)
Child windows (subwindows like widgets or panes in a top level window)
Child windows again come in two characteristics:
logical child
real child
A logical child window just consists of its position, dimension and layer and are managed by the toolkit. From the view of the operating system there's just one top level window. The toolkit is it that manages its internal state to give the impression of independent sibling windows in the toplevel window.
A real child window is manages by the operating/graphics system. Such real child windows may share their graphics context with their parent and sibling. However OpenGL only works well if the window into which a OpenGL context is created has its very own graphics context. Thus any OpenGL child window inevitably will have its very own graphics context and graphics system window object. Most graphics systems out there don't properly support applying shapes onto child windows (only toplevel windows, and then this also conflicts with OpenGL).
So this boils all down that it's virtually impossible, nor advisible to try to "layer" an OpenGL window on top of a sibling. It may work in some circumstances, but most of the time it won't.
That's the bad news.
The good news are, that you simply looked in a slightly wrong direction. I hereby direct your view towards QGraphicsView. QGraphicsView supports OpenGL as a backend, you can also write your own OpenGL renderer code to be executed within a QGraphicsView. But furthermore QGraphicsView can also be used for rendering widgets, also using OpenGL. So all you have to do is putting both your OpenGL rendering code and your widget into a common QGraphicsView scene and are done. And here is a tutorial http://www.crossplatform.ru/node/612 the result of the tutorial looks like this:

Related

Move splitters in design mode

When i add splitters, it acts as a layout, but also allows to resize the widgets in runtime. So, for example, i managed to lay out my widgets in this way:
Therefore, i can resize my widgets in runtime. As i noticed, this function is also available in designer mode, but it doesn't work properly. I tried to hover over my splitter and drag it in designer mode, but it only replaces the entire widget.
That is how does my main window look like in QtDesigner. I haven't tried to code yet. The problem is, that even though i used to set a stretch factor, my widegt's look in designer mode and in runtime completely differ. They have another sizes.
So, what are the problems:
Firstly, i can't change my widgets sizes properly, using stretch factors. I don't know, i tried to change size policies, but i did't manage to see an effect. I have somehow changed size of the vertically oriented widgets, but when speak about horizontal orientation - stretch factor and size policy doesn't change anything at all.
Secondly, i can't move my splitter in designer mode. It's position is constant, by default, it's always somewhere in the middle.
Thirdly, i have bugs (i think so) with my widget sizes in designer mode. They differ with widget's sizes in runtime.
Question:
So, how can i change widget's sizes properly? Maybe there's a way of moving a splitter in designer mode - do newer versions of Qt have it? Currently i'm using Qt 5.9.9. Also, why these bugs, and are they bugs at all. Maybe i just should update my Qt to newer versions to get access to newer functionalities?
Comment: I'm not sure if stretch factors work with layout as they do with widgets. I'm using layouts exactly the same way i use widgets. My layout's wrong(maybe) use may have caused this problem. Anyways, i'm entirely new to Qt, and may not know something to understand it completely.

Relative UI unit in QT Widgets QSS stylesheets

My current UI doesn't use QT widgets paint and it's mostly done with QSS markup. The current styles are defined in pixels and I could not find anything in the QT documentation that allows the styles to be defined as relative unit as opposed to pixels. I would like to know if it's possible to use something relative then tie that unit to a ROOT font-size. In case I need to adjust for a particular screen size like a battery charger IOT device that has a small screen, while my main UI was designed for very large screens (27 inch monitor). So instead of me styling a button just for the IOT device, I shrink the base unit (technique similar to web responsive like REM) then everything like fonts, padding, buttons shrink proportionally. Is that something that QT supports?
To my knowledge vanilla Qt Widgets don't support free scaling at all. Recently high-DPI display support was added, but it only scales in fixed ratios (e.g. 1:2). There are other options to get scaling in Qt applications:
Use QML (didn't try this yet myself, but it's developed with adaption to different displays in mind)
Use QGraphicsScene with QGraphicsWidget
Use QGraphicsScene with custom graphics objects that implement the behavior you need
Roll your own widgets
I'd love to stand corrected on this answer - maybe in a future Qt version...?

How to avoid adding excess 1 pixel spacing by Qt Designer

I'm working on application for embedded and we have 256x64 grayscale screen. Qt 5.3 perfectly renders on that screen with -platform linuxfb option. Obviously, we save every pixel of space, so I faced with trouble: Qt Designer adds excess 1 pixel spacing for every layout element deeper in hierarchy. So they accumulate for the most deep widgets. More precisely, for some reason child element of layout components gets coordinates (1,1) relative to parent. So, it's true for every widget except for root widget. Picture below demonstrates accumulated spacings (thin and thick red lines), and (1,1) coordinates of the very first child widget.
I believe it's Qt behavior itself, not just Qt Designer issue (not tested yet). But I can't work further even if it's shown in Designer only: I need to have pixel-exact view while designing.
Of course, every spacing and margin of every component in form set to 0.
Manual coordinates assigning (from code) eliminates the problem of course, but I need to generate code by uic.
So, my question is: how to avoid such spacings? Fixing Qt core sources can be (hard) option too, since anyway we recompile Qt for the project.
Mirror post on Qt forums
Thanks.
Ilia.
If you select Form > View Code, you can see that the geometry is not actually used for widgets which are inside a layout. So the numbers you see in the Property Editor are purely informational and have no relevance to the eventual code that is generated from the ui file (which is why they are greyed out).
The one pixel offset is there because Qt Designer needs space to draw the red boxes around layouts. They have to be be represented somehow, so I don't see how this can be avoided given the way Qt Designer currently works. If you want a more accurate reprentation of the final results, I suppose you will have to show a preview.
There is a facility in Settings > Preferences > Embedded Design that allows you to specify device profiles (which determine things like style, font, and screen resolution). This will add a new entry to the Preview In menu, which should allow you to refine the accuracy of the previews even further.

Why do custom QWidgets, but not the built-in ones, have nonzero margins?

This is a screenshot of a QFormLayout holding a series of widgets. Note that the top and bottom input widgets are not horizontally aligned to the middle two rows. Note also that the labels on the left are not vertically aligned to the middle two rows.
The difference is that the top and bottom widgets are plain QLineEdit and QTextEdit widgets, the second row is a QWidget with a QHBoxLayout holding a QSpinBox and QDateTimeEdit, and the third is a QStackedLayout containing QWidgets each with a QHBoxLayout and API-supplied widgets inside those.
It looks like these middle two have extra margins. I can (partially) improve the situation by calling QLayout::setContentsMargins on the plain QWidgets' layouts. In fact, in the image above I already have, without that it's worse.
I haven't interfered with styles in the application, it's all system-default. This seems to affect Qt5 on Ubuntu 15.04, I don't think I saw this back when it was a Qt4 application.
I tried setStyleSheet ("QWidget {margin:0;}") in the top-level widget, that introduced all sorts of problems. I also tried the variation setStyleSheet (".QWidget {margin:0;}") but that had no effect. QLayout::setSpacing also had no effect, and setting padding:0 in the stylesheet doesn't fix it either.
Nothing I've tried seems to bring the spacing around these custom-layout QWidgets in line with the API-supplied widgets.
What have I missed? Thanks.
What you observe is both the struggle of multi-platform ui and the simple fact that some widgets are horrible. Given a limited amount of time and a big task, dev teams will not treat fairly the set of features. Powerful widgets and layouts like standard widgets, QGridLayout, will be maintained day and night to be defect free while legacy widgets like QStackedWidget will be pushed at the bottom of the maintenance queue.
I tried to reproduce your issue using designer alone and here is what I got (Qt 4.8) :
What you can see:
The second line with a widget container has great marging
The third line doesn't even show the combo box (I swear it's there!!).
My two cents :
There is a difference in behavior in the second row. Because I used Qt4 and you Qt5, and we both set the QHBoxLayout margin to zero then it means there is a potential regression at play, either in Qt5 or the linux implementation. So this confirms what you suspected.
QStackedWidget is horrible. It is the usual widget provided to give quick and basic functionality rather implementing the real deal. Here it would be a widget with a QStackedLayout. Like I said I suspect those kind of widgets to receive less love when big development efforts are required.
In these situations, use QGridLayout instead of a QStackedLayout of widgets with layout of widget. It will solve the issue of labels not being aligned. Difficult to set up at first but the result is usually neat.
By the way, I switched to a widget with a stackedlayout and here is the result :

Can't embed OpenGL window into QWidget with XReparentWindow

I'm trying to add better UI for an OpenGL-based program with Qt. Since I can modify that program it's not hard to get the window ID. So I think embedding it into a QWidget would be a good idea. However, it doesn't work like I expected:
After XReparentWindow is called, the OpenGL window lose its decoration, but the position didn't change.
If I use XConfigureWindow to move it to position (0, 0) relative to parent it goes to the top-left corner of the screen, but not the QWidget.
After reparenting, a third window can cover the QWidget, but nothing can cover the OpenGL window.
X11 reported no errors during the whole operation.
It seems the parent of the OpenGL window has been set to the root window instead of my QWidget. What should I do to make it work correctly?
You can replace your current OpenGL window with a QGLWidget which provides an OpenGL context and can be placed into a Qt window directly.
I'm not sure Qt supports XReparentWindow calls like that. The docs don't seem to say it does, so it's probably a bad idea to use it. You could try QWidget::create() instead.

Resources