Qt: Setting gradient on Layout - qt

I have a QHBoxLayout with several items in it. In the space occupied by the QHBoxLayout, I want a vertical gradient from black to white (behind the items in the QHBoxLayout). However:
QHBoxLayouts do not have style sheets, so that's out
QHBoxLayouts do not have palettes, so that's out
And these are the only two methods of setting gradients that I've found (they were all intended to work on widgets). I tried setting the stylesheet of the parent widget to include:
QHBoxLayout {
background-color: red;
}
to see if css could be worked in that way, but this does nothing.
Is it possible to give a layout a background gradient with Qt?
(I am using PyQt5, if that's relevant)

I'm not expert to PyQt, but in plain Qt you can put your QHBoxLayout inside a QWidget and then apply a layout to the widget (the buttons above the designer).
This is what the object tree looks like when done (the selected item has the gradient)
And this is how my little mock up came out. (If you like the buttons to be non-transparent, add a stylesheet for the background)

Related

Why won't QGroupBox widgets dynamically resize with rest of window?

I have a QMainWindow with the widgets laid out in a grid. They all resize proportionally when the window resizes as expected, except for the widgets placed inside a QGroupBox. The QGroupBox itself resizes, but the widgets inside just stay on the same place. If I apply a lay out on the QGroupBox, the widgets loose their original positions. Note that I'm using the .ui file with PyQt4. You can get the file here.
And this is what happens:
From Qt documentation on QGroupBox:
QGroupBox doesn't automatically lay out the child widgets (which are
often QCheckBoxes or QRadioButtons but can be any widgets).
There is an example showing how to setup a layout for a QGroupBox (which is the same a setting up a layout for any QWidget based object meant to store other objects, like QFrame for instance).
You must create a layout, call QGroupBox::setLayout and then add widgets to the layout. If you use QtCreator, right-click the QGroupBox and select the layout you want to use for it from the context menu.

QWidget overrides Qscrollarea CSS

I'm trying to implement a complex UI in QT with a lot of customization.
This is what I'm trying to achieve (photoshop file)
This is my current screen, I just discovered that the original CSS sheet which was developed by someone had a global color setting for Qwidget, this color is being rendered in a lot of widgets, but the problem is that it's overiding the Scroll, which prevents me from changing the color on the left side (please see the blue dot)
The code for this is:
QWidget {
background-color: #1a1d21; /* software canvas background color */
border: 0px solid black;
}
QScrollArea {
background-color: #262a30;
border: 1px solid black;
}
I tried removing the color code in the CSS for QWidget which effected Qscrollarea and the color chosen was properly rendered, but some problems came up:
It removed color for a lot of widgets that I had and now it's all white, now I will have to specify individually which worries me, because it's not just time consuming considering the size of my application but also because it sometimes it doesn't work.
What also worries me is that I tried specifying background color to the specific widget and it didn't work, I've tried the placeholder object and class together and separated - QDockWidget / QDockWidget and also the real widget that is being called : QTabWidget / tabWidget. So I don't know whether it's because I'm doing something wrong in the code and not using still the correct object to change the color or if Qwidget is actually overriding the color (which makes me confused because I thought that child always overrides parent in CSS)
Note: I'm a designer and newbie in Qt and programming.
For every Qt widget you can provide an unique name. Then you can use that name to setup the desired widget style in the stylesheet (CSS)
If you're not using Qt Creator, widget name can be set using i.e. QWidget::setObjectName("scrollArea");

Semi-transparent QWidget over QGLWidget: Strange results

I have a full size QGLWidget which paints the application background using QPainter (might change to native openGL commands in the future).
On top of this QGLWidget I use QWidgets (non-GL) for the user interface elements. These are, for example, QLineEdits and QPushButtons. I put them into a custom painted QWidget which uses semi-transparent background painting. The paintEvents of the QLineEdit and QPushButton are overwritten and use semi-transparent backgrounds, too.
The whole UI should look like the following (This is a screenshot where I disabled OpenGL and used QWidget instead of QGLWidget for the background. Note the semi-transparent top bar which also draws a shadow (within its own region)):
When the QLineEdit has the focus, it should have a higher opacity but still not fully opaque:
So now, with OpenGL enabled (The background then is a QGLWidget), the semi-transparent widgets above don't paint on top of the background but on (it seems to be) uninitialized data. The image shining through the top bar is sometimes the whole window itself and sometimes other windows currently being on my desktop.
This currently looks like the following (In this screenshot, the data on which the semi-transparent painting operations are painted on seems to be an image of the widget itself, having an offset.):
When I wrote text into the line edit (here: "This is some text which has been there before!"), removed it and set the focus back to the background widget (so the magnifier icon and the placeholder text appear), the previously painted things still shine through (Note that the visible border should not be visible anymore, but also still shines through):
So the problem is: Instead of being painted on top of the underlying widgets, the semi-transparent widget is painted on top of the old results, initially being something like "uninitialized memory".
Why does this happen? How can I solve the problem?
Things you should know before answering:
The background scene is a composition of tiles which are rendered off-screen. So it can be painted very fast and repainting of the background for every little change of the overlay isn't problematic.
The top bar is a custom QWidget with manual painting and arrangement of the contained two widgets (the button and line edit).
The two widgets overwrite the paintEvent, only draw their own (semi-transparent) background when they have focus and don't use frames already provided by Qt. So the white border in the second screenshot is drawn in my custom paintEvent.
I want the background and the composition of overlay widgets to be separately implementable. The background is an AbstractMapView which has some concrete map view classes. The whole window is an AbstractView (there are multiple concrete views, too), which contains both a concrete map view and the overlay widgets, composed in a way itself decides. Therefore, I don't want the logic of the overlay widgets to be part of the underlying map view. (I hope you understood this, as it is a bit complicated.)
This sounds like an issue where the GL content (i.e. your background aka the QGLWidget) is not in the Qt context. While I'm not a pro on GL painting with Qt, you may want to look at this discussion regarding GL painting and a QLabel for some direction/potential hints.
http://www.qtcentre.org/threads/40335-QLabel-on-top-of-a-QGLWidget-background-issue
In short, we here at the office use OpenGL painting and offscreen rendering of maps and it's very important to make sure Qt is aware of the pixels so your foreground widgets can have the semi-transparency applied to their backgrounds.
The particular product we use also renders the map in tiles and supports providing the GL output in a buffer (i.e. it's call a snapshot and is provided as a bitmap) at which point we use the paintEvent of a regular QWidget to paint the buffer so that the painted pixels are in Qt context.
You can define a Qframe with Qt::SplashScreen flag as the search box and set its opacity. Put your widgets inside it such as the search textbox and positon it where it should appear on the mainwindow. It will also be a good idea to reposition it as the mainwindow is moved or resized overriding its moveEvent.

QT Transparent Layout

I am using a vertical layout (QVBoxLayout) to manage buttons. I would like to make its background color as 50% black transparent. Is it possible ?
sw
Depending where you want the border of the transparent area, you will need to group the buttons in a widget (as SigTerm said) and then you can assign a color either via the palette
QPalette palette = widget->palette();
palette.setColor(QPalette::Window, QColor(100,100,100,100));
widget->setPalette(palette);
or use a stylesheet
widget->setStylesheet("QWidget{background-color: rgba(100,100,100,100);}";
the stylesheet has the advantage that you can style all of your application from one spot that is not in the code and set an application wide stylesheet via QApplication::setStylesheet(QString)
Ahem... it's been a while since I used Qt, but as far as I know, QVBoxLayout has no background color, so no, it isn't possible. Layout isn't a widget and it isn't being painted at all, it only manages child widget sizes.
If you want to create colored layout, you'll probably have to create a widget with whatever color your want, and then parent QVBoxLayout to that widget.
It'll become more fun if you want color of all layout's children to be affected by color of QVBoxLayout's parent, but I think that "Embedded Dialogs" demo from Qt4 demo may give you an idea about how it can be done.

Is there a way to emulate a QGroupVBoxLayout?

I am using Qt designer and I know how to use a QVBoxLayout and QGroupBox but it seems there is no such thing as a QGroupVBoxLayout. So I have to put a QVBoxLayout inside of a QGroupBox but if I modify the dimensions of one I have to do the same to the other. Is there a way to make them change dimensions together directly from QT designer?
Add a QGroupBox to the form
Add widgets to the QGroupBox at positions where you would expected to be when the layout is applied (it doesn't have to be precise)
Select the QGroupBox and click the "Lay Out Vertically" toolbar button (the one with three blue vertical bars)

Resources