Is it possible to set the opacity of qt widgets? - c++

I know that there is a function QWidget::setWindowOpacity(qreal level) but as written in the documentation this does only work for windows.
Is there a way to make widgets that are lying inside layouts opaque too?
What I'm trying to do is an animation where widgets are fading in. I once did that with a preferences-dialog and there it worked.
So do you think there is a way or a work-around to achieve opacity for widgets inside layouts? How would you do that?
Thanks in advance!

Just use QGraphicsOpacityEffect in order to achieve this effect.
Qt4: http://doc.qt.io/qt-4.8/qgraphicsopacityeffect.html
Qt5: http://doc.qt.io/qt-5/qgraphicsopacityeffect.html
Qt6: https://doc.qt.io/qt-6/qgraphicsopacityeffect.html

Well for widgets inside mainwidow appear to have setAutoFillBackground(False) by default.
to make it fade in fadeout u need to to use QGraphicsOpacityEffect along with setAutoFillBackground(True)
a small example: write inside the widget which is called inside the mainwindow
op=QGraphicsOpacityEffect(self)
op.setOpacity(1.00) #0 to 1 will cause the fade effect to kick in
self.setGraphicsEffect(op)
self.setAutoFillBackground(True)

SetWindowOpacity works for me in Linux. I used code like this to change window opacity, (value is from 0 to 100):
setWindowOpacity(qreal(value)/100);

mywidget.setStyleSheet('background-color:rgba(r, g, b, alpha);')
works for me

In Qt5 you can use css to make widgets transparent
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDialog dialog;
dialog.setStyleSheet(QLatin1String("#LolButton{color: transparent; background-color: transparent;}"));
QPushButton button(&dialog);
button.setText("Button");
button.setObjectName(QStringLiteral("LolButton"));
QObject::connect(&button,&QPushButton::clicked,[](){
QMessageBox msg;
msg.setText("LolButton omg");
msg.exec();
});
dialog.show();
return a.exec();
}

Related

Qt set common background for all dialog boxes

I am working on developing a Qt 5 widgets desktop application where I want to give a common background for all windows and dialog boxes that pop up. The problem is that for each window I have to specify the same piece of code over and over again to load the same background. I am also using paint function override so as not to distort the background when window is resized. Here's my code:
SettingsDialog::SettingsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SettingsDialog)
{
ui->setupUi(this);
pixmapBg.load(":/images/google-material-design-wallpaper-10.jpg");
}
void SettingsDialog::paintEvent(QPaintEvent *pe)
{
QPixmap pixmapBgL = pixmapBg.scaled(this->size());
QPalette palette;
palette.setBrush(QPalette::Background, pixmapBgL);
this->setPalette(palette);
}
Is there a way to accommodate this in Qt using a single file rather than mentioning it for each window?
Yes, you can! You will have to provide your own stylesheet, or initialize your application by calling QApplication::setStyleSheet(styleName).
Follow up from comment: setStyleSheet is the quickest approach, i.e.
qApp->setStyleSheet("QDialog, QMessageBox {background-image: url(:/images/google-material-design-wallpaper-10.jpg);}");
assuming you have a valid QApplication reference qApp. Note that you can also refer to your custom subclasses as well, if you want to refine the scope of the stylesheet.
Here is some code using QApplication::setStyleSheet:
QString styleSheet = "QWidget{\
background-color: yellow\
}"//style sheet in CSS style
int main(int argc, char** argv){
QApplication app(argc, argv);
app.setStyleSheet(styleSheet);//will set all the QWidgets' background color to yellow
return app.exec();
}
There is actually a background-image property but I'm not sure about which widgets are supporting it so you can check right there.

Is it possible to remove borders a single QWidget around a QMainWindow?

This is a very simple problem to reproduce. Create a new project with Qt Creator with a QMainWindow. Using designer add a single widget (it doesn't matter which one) and then use the right button to set a layout (any layout as with a single widget the results are always the same).
There will be a gray border around the widget. I would like to remove this border so that the widget occupies the entirety of the main window area (which Qt always names centralWidget). Basically the single widget is all I want to see.
Is this possible? If so, how?
Yes, it's possible. All you need is setting margins of that centralWidget to 0. (note that you should first set up a layout)
In properties panel set the following properties to 0.
layoutLeftMargin
layoutTopMargin
layoutRightMargin
layoutBottomMargin
Also note that using a QWidget (not QMainWindow) as your main app window is perfectly valid, so if your app has only one widget, you won't need a QMainWindow at all. It's enough to show that widget.
The answer above is the right answer but I also wanted to share what I've found out. I basically wanted to create a QGraphcisView that occupies the entire screen. and I thought of the above method, which Hi I'm Frogatto answered. Another way is to create a simple app with this code:
#include <QCoreApplication>
#include <QApplication>
#include <QGraphicsView>
int main(int argc, char *argv[])
{
//QCoreApplication a(argc, argv);
QApplication app(argc, argv);
QGraphicsView *view = new QGraphicsView();
view->showFullScreen();
return app.exec();
}
And this .pro file:
QT += core gui widgets
CONFIG += c++11
TARGET = Test
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
This also does what I wanted!. Maybe it can help someone.

Qt - Draw a fully transparent window in Windows without using WA_TranslucentBackground

I need to draw transparent window (either QLabel or QFrame or QWidget), but without using WA_TranslucentBackground. The reason for that is that the windows will contain other child widgets rendered through OpenGL, and using that property makes those windows invisible on Windows, as documented here. This works fine in Mac though, I need a different solution on Windows only, as it does not work there. I tried this: setting a blank pixmap. But it still shows up with a grey background:
#include <QApplication>
#include <QLabel>
#include <QBitmap>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel l;
l.setWindowFlags(Qt::FramelessWindowHint);
QPixmap p("");
l.setPixmap(p);
l.setScaledContents(true);
l.resize(300, 500); //just to test my idea
l.setMask(p.scaled(l.width(),l.height(),Qt::IgnoreAspectRatio,
Qt::SmoothTransformation).mask());
l.show();
return a.exec();
}
Can anyone suggest any other means of achieving this on Windows, i.e a fully transparent window? Platform - Qt 5.3.1, 32 bit.
P.S - It need not behave like translucent window, i.e where the background can be clicked through the transparent parts of a widget rendered though WA_TranslucentBackground. Here as long as it is transparent it will be okay, it need not be clickable 'through'.
I am on Windows (Qt 5) and use the following to create a Semi-Transparent Widget:
setWindowOpacity(0.6);
setStyleSheet("QWidget{background: #000000}")
It should work if you set the opacity to zero.
I use this together with the Windows flags "framelessWindow" and "Tool" to darken the background of the screen.
transparency can be achieved by enabling blur behind window and by setting windows attribute to WA_TranslucentBackground
setAttribute(Qt::WA_TranslucentBackground);
QtWin::enableBlurBehindWindow(this);
required , cpp include : include<QtWin>, project file include : QT += winextras
the method enableBlurBehindWindow() has two more overload ,you can look those on this documentation
For child widgets you can use
setStyleSheet("background:transparent");
Unfortunately this is not possible on Windows. You can set transparency for widget with color with alpha-channel like this: setStyleSheet("background-color: rgba(255,0,0,50%);");. But whis is doesn't work for top level widget until you set WA_TranslucentBackground. Without this flag alpha-channel doesn't work and you get black window. So the only solution is use WA_TranslucentBackground. And then do OpenGL painting like Qt documentation says:
To work around this issue you can either just use Qt to render
everything and not OpenGL, or you can render the OpenGL into a pixmap
and draw that onto your widget instead.

How do I just put header and some content under it in Qt Designer?

QtCreator's designer allows you to edit user interface graphically. I was just trying to make some sense of it - what I wanted was a header text centered in the middle and some widget under it, like this:
But my results look like this, when using vertical layout:
I placed QLabel on top and QOpenGLWidget on bottom - I only used QOpenGlWidget because it has black background on screenshot. What I really plan on doing is using another QWidget. I used vertical layout then. So how do I get the result on the first image, using QLabel and QWidget?
Qt's use of XML is not a replacement for HTML.
HTML is designed for marking up web pages. Qt's widgets are not web pages!
It appears that you're looking at the box with the text 'content' and thinking of a generic widget. I see that and see a QLabel, which is derived from QWidget after all.
It's probably easier to explain in code how I would go about this, which you can then translate to doing the same in Qt Creator.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Create a root widget (this could also be a QMainWindow, or any other widget)
QWidget* pWidget = new QWidget;
// Layout to arrange the widgets vertically
QVBoxLayout* pBoxLayout = new QVBoxLayout;
pWidget->setLayout(pBoxLayout);
// The header widget
QLabel* pHeader = new QLabel("Header");
pHeader->setAlignment(Qt::AlignCenter);
pHeader->setMinimumSize(200, 20);
pHeader->setMaximumSize(200, 20);
QFont font = pHeader->font();
font.setBold(true);
font.setPixelSize(16);
pHeader->setFont(font);
// the content widget
QLabel* plabel = new QLabel("content");
plabel->setMinimumSize(200, 200);
plabel->setMaximumSize(200, 200);
plabel->setStyleSheet("background-color: rgb(182, 182, 182); border: 5px solid black;");
plabel->setAlignment(Qt::AlignCenter);
pBoxLayout->addWidget(pHeader);
pBoxLayout->addWidget(plabel);
pWidget->show();
return a.exec();
}
As you can see here, I've styled the content widget with the use of a Style Sheet. This is really the easiest method, after a bit of practice with them.
The resulting code produces a widget which looks like this: -
You can play with dimensions and fonts to match your original image exactly.

Qt window frame design

How to apply the design of window frame?
Not Qt::FramelessWindowHint , but Windows 7 frame
edit:
How to create your own frame in QStyle?
If you talk about frame style, it will be good solution.
#include <QtGui/QApplication>
#include <QWindowsStyle>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyle(new QWindowsStyle);
MainWindow w;
w.show();
return a.exec();
}
But Qt has many other styles - learn about QMotifStyle and QCleenlooksStyle... [link]
You can try Coffe or Pagefold styles.
You can set a style sheet on an individual child widget, on a whole window, or even on a whole application by calling QWidget::setStyleSheet() or QApplication::setStyleSheet().
Frames are usually the business of the windowing system and cannot be freely re-styled by the application. You'd probably need to create a frameless window with mentioned hint and paint your own title bar/frame inside the widget.