C++ over Qt : Controlling transparency of Labels and Buttons
You can set transparency of QLabel or QPushbutton by setting the stylesheet :
ui->label->setStyleSheet("background-color: rgba(255, 255, 255, 0);");
ui->button->setStyleSheet("background-color: rgba(255, 255, 255, 0);");
You can also add background-color: rgba(255, 255, 255, 0);
to the styleSheet property of the widget in the designer.
The fourth parameter is alpha. You can also have semi-transparent widgets by setting alpha to some value more than zero :
ui->button->setStyleSheet("background-color: rgba(255, 255, 255, 50);");
Is it possible to set the opacity of qt widgets?
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
Qt: How to add two widgets (say QPushButton) to the status bar, one to the left and other to the right side?
You can add two buttons to a layout in a widget and add the widget to the status bar using QStatusBar::addWidget
:
QWidget * widget = new QWidget();
QPushButton * leftBut = new QPushButton("Left");
QPushButton * rightBut = new QPushButton("Right");
QGridLayout * layout = new QGridLayout(widget);
layout->addWidget(leftBut,0,0,1,1,Qt::AlignVCenter | Qt::AlignLeft);
layout->addWidget(rightBut,0,1,1,1,Qt::AlignVCenter | Qt::AlignRight);
ui->statusBar->addWidget(widget,1);
How to add custom widget (with layout) overlapping another custom widget (with layout) pyqt
The main problem is that a widget can only have one layout manager, and it's not possible to set another layout if one already exists. It should also not be responsibility of a child widget to set the layout on a parent.
Another important aspect is that box layouts do not allow overlapping widgets, so the only solution is to use a grid layout and specify the span depending on how the overlapping widgets should be placed.
Considering the above, there are two possibilities: use the grid layout on the widget containing the buttons and add the labels on top of them, or the other way around. In the following example, I'm doing the latter. Note that in this case the widget with the labels will not be the child, but the parent.
class TitleData(QWidget):
def __init__(self,title="Title", data="Data", buttons=None, **kwargs):
super().__init__(**kwargs)
self.title = title
self.data = data
self.title_label = QLabel(self.title)
self.data_label = QLabel(self.data)
for label in self.title_label, self.data_label:
label.setAttribute(Qt.WA_NoSystemBackground)
label.setAttribute(Qt.WA_TransparentForMouseEvents)
label.setAlignment(Qt.AlignHCenter)
self.l = QGridLayout(self)
self.l.addWidget(self.title_label, 0, 0, alignment=Qt.AlignTop)
self.l.addWidget(self.data_label, 1, 0)
self.l.setRowStretch(1, 1)
if buttons:
self.l.addWidget(buttons, 0, 0, 2, 1)
buttons.lower()
class DataDisplay(QWidget):
def __init__(self, **kwargs):
# ...
self.xxx = TitleData(buttons=self.sub_widget)
self.l = QVBoxLayout()
self.l.addWidget(self.xxx)
# ...
Note that the button widget is lowered to ensure that it's put behind the labels.
Please consider that this approach is not very good from the UX perspective, at least with the current implementation: buttons could keep a focus rectangle even if they're flat, and this could make the label difficult to read (imagine letters that have vertical lines or that could become different letters with a vertical line, like "o" becoming a "d" or a "b"). Creating two classes for this is also unnecessary, as you can do the same with a simple class, and you could eventually use stylesheets to improve readability:
class TitleDataButton(QWidget):
clicked = pyqtSignal(int)
def __init__(self, title='Title', data='Data', buttons=True, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title = title
self.data = data
self.title_label = QLabel(self.title)
self.data_label = QLabel(self.data)
for label in self.title_label, self.data_label:
label.setAttribute(Qt.WA_NoSystemBackground)
label.setAttribute(Qt.WA_TransparentForMouseEvents)
label.setAlignment(Qt.AlignHCenter)
layout = QGridLayout(self)
layout.addWidget(self.title_label, 0, 0, 1, 2, alignment=Qt.AlignTop)
layout.addWidget(self.data_label, 1, 0, 1, 2)
layout.setRowStretch(1, 1)
if buttons:
self.right_button = QPushButton()
self.right_button.pressed.connect(self.rightF)
self.left_button = QPushButton()
self.left_button.pressed.connect(self.leftF)
for c, button in enumerate((self.left_button, self.right_button)):
layout.addWidget(button, 0, c, 2, 1)
button.setMinimumSize(30,120)
button.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
button.lower()
button.setFocusPolicy(Qt.NoFocus)
button.setStyleSheet('''
QPushButton {
border: 1px solid transparent;
border-radius: 2px;
}
QPushButton:hover {
border-color: darkGray;
background: lightGray;
}
QPushButton:pressed {
background: darkGray;
}
''')
def rightF(self):
self.clicked.emit(1)
def leftF(self):
self.clicked.emit(-1)
As above, the buttons are lowered so that they're placed under the labels.
QLabel with pixmap: prevent pixmap's color change in disabled state
A (not so complicated) way to achieve that, is to draw the pixmap by yourself. Instead of subclassing QLabel
and override paintEvent
, you can install an event filter in your label and listen for QPaintEvent
's only.
Have the filter:
class Filter : public QObject
{
Q_OBJECT
public:
Filter(): QObject(nullptr) {}
bool eventFilter(QObject *watched, QEvent *event);
};
In its eventFilter
method, always return false, but when you draw the pixmap:
#include <QPaintEvent>
#include <QPainter>
#include <QStyle>
bool Filter::eventFilter(QObject *watched, QEvent *event)
{
if(event->type() == QEvent::Paint)
{
QLabel * label = dynamic_cast<QLabel*>(watched);
QPainter painter(label);
QPixmap pixmap = label->pixmap()->scaled(label->size());
label->style()->drawItemPixmap(&painter, label->rect(), Qt::AlignHCenter | Qt::AlignVCenter, pixmap);
return true;
}
return false;
}
Instantiate and install the filter, something like:
ui->setupUi(this);
Filter * filter = new Filter();
ui->label->installEventFilter(filter);
/* don't forget to call:
delete filter;
somewhere later */
In my example code, I scaled the pixmap to fit the label size and centered it both horizontally and vertically, but you can adjust all this, according to your needs.
Moreover, the same filter can be installed to more than one label, since the logic works fine for them all. More on event filtering here.
How to set window and it's graphicScene transparent(using slider) and leave only QPushButton visible
Here is one way.
class MainWindow(QDialog):
def __init__(self):
QDialog.__init__(self)
# these two lines are needed to get a transparent background in windows
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
# rest of class definition unchanged
class MainGraphicsWidget(QGraphicsView):
def __init__(self, parent=None):
super(MainGraphicsWidget, self).__init__(parent)
# set transparent background color for the widget itself
self.setStyleSheet("background-color: #00000000")
self._scene = QGraphicsScene()
self.setScene(self._scene)
# create of slider and connect to slot for changing opacity.
self.transpSlider = QSlider()
self.transpSlider.setStyleSheet('background-color: #00000000')
self.transpSlider.setRange(0,255)
self.transpSlider.valueChanged.connect(self.set_opacity)
self.transpSlider.setValue(255)
# rest of __init__ unchanged
def set_opacity(self, value):
brush = self.backgroundBrush()
color = brush.color()
color.setAlpha(value)
brush.setColor(color)
self.setBackgroundBrush(color)
Note that I've changed the range of the slider to 0-255 to make changing the opacity from fully opaque to fully transparent easier.
Related Topics
Why Are Override and Final Identifiers with Special Meaning Instead of Reserved Keywords
Why Is '"Literal"' Encouraged to Decay to 'Const Char*' in C++ Argument Type Match
How to Create a N Way Cartesian Product of Type Lists in C++
When Did "And" Become an Operator in C++
What Is a Cross-Platform Way to Get the Current Directory
Does the Evil Cast Get Trumped by the Evil Compiler
When to Mark a Function in C++ as a Virtual
Getopt Fails to Detect Missing Argument for Option
Why How to Implicitly Convert an Int Literal to an Int * in C But Not in C++
What Does a Comma Separated List of Values, Enclosed in Parenthesis Mean in C? a = (1, 2, 3);
Why Double Can Store Bigger Numbers Than Unsigned Long Long
Rotating a 2D Pixel Array by 90 Degrees
Specializing Single Method in a Big Template Class
Why Doesn't the Program Crash When I Call a Member Function Through a Null Pointer in C++
A Better Way to Split a String into an Array of Strings in C/C++ Using Whitespace as a Delimiter
How to Implement an Easy_Bind() That Automagically Inserts Implied Placeholders
Why Ld_Preload Doesn't Work for One of Loaded Shared Libraries