Is it possible to change the height of a QProgressBar? - python

I'm trying to change the height of the inner bar.
I already tried to change the height of the chunk, but the hole bar just vanished.
I also tried to change the chunks padding, but nothing happend.
from PySide2 import QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.setStyleSheet("""
QProgressBar {
background-color: #C0C6CA;
border: 0px;
padding-top: 11px;
padding-bottom: 10px;
}
QProgressBar::chunk {
background: #7D94B0;
}
""")
self.progress_bar()
def progress_bar(self):
layout = QtWidgets.QHBoxLayout()
progress = QtWidgets.QProgressBar()
progress.setTextVisible(False)
progress.setValue(35)
layout.addWidget(progress)
self.setLayout(layout)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
I want a chunk with the same height of the progressbar itself.

The ::chunk subcontrol is used to change the chunk progress (i.e. the rectangles in the progress bar).
If you want to have a progress bar with the same size of its background, remove the padding:
self.setStyleSheet("""
QProgressBar {
background-color: #C0C6CA;
border: 0px;
padding: 0px;
// height: 100px; // To change the progress bar height
}
QProgressBar::chunk {
background: #7D94B0;
width:5px
}
""")
It will display:

Related

setGeometry not workingin pyqt5?

I am trying to set the width height of a QWidget percentage wise. But since we cannot do something like min-height:20% using QSS. I tried to use setGeometry function and recall this function on window resize event, but somehow it don't work, below is my code:
class mainwindow(QMainWindow):
def __init__(self):
super().__init__()
stylesheet = """
#mainwindow{
border: 0px;
background-color: #222;
}
"""
scanelestylesheet = """
#scanelecontainer{
border: 1px solid #1a1a1a;
background-color: #222;
}
"""
scanstusconstylesheet = """
#scanstuscon{
border: 1px solid #1a1a1a;
background-color: #fff;
}
"""
container = QWidget()
container.setObjectName("mainwindow")
container.setContentsMargins(100, 100, 100, 100)
self.setCentralWidget(container)
self.setStyleSheet(stylesheet)
self.setWindowTitle("Neehack")
widget = QWidget()
widget.setObjectName("scanelecontainer")
widget.setAutoFillBackground(True)
lay = QVBoxLayout(container)
lay.addWidget(widget)
effect = QGraphicsDropShadowEffect(
offset=QPoint(3, 3), blurRadius=25, color=QColor("#1a1a1a")
)
widget.setGraphicsEffect(effect)
widget.setGeometry(0, 0,200, 20)
widget.setStyleSheet(scanelestylesheet)
scanstuscon = QWidget()
scanstuscon.setObjectName("scanstuscon")
scanstuscon.setAutoFillBackground(False)
scanstusconlay = QVBoxLayout(widget)
scanstusconlay.addWidget(scanstuscon)
scanstuscon.setGeometry(10,10, 200,200)
scanstuscon.setStyleSheet(scanstusconstylesheet)
self.resize(1200, 800)
How do I set a QWidget size based on its parent's percentage or why isn't setGeomtry not working here?
The objective of the layouts is to handle the geometry of the widgets so setGeometry will not work. On the other hand, using setGeometry to modify the size together with resizeEvent to establish a percentage of the size is unnecessary since it is enough to set the stretch factor in the layout:
class Mainwindow(QMainWindow):
def __init__(self):
super().__init__()
stylesheet = """
#mainwindow{
border: 0px;
background-color: #222;
}
"""
scanelestylesheet = """
#scanelecontainer{
border: 1px solid #1a1a1a;
background-color: #222;
}
"""
scanstusconstylesheet = """
#scanstuscon{
border: 1px solid #1a1a1a;
background-color: #fff;
}
"""
container = QWidget()
container.setObjectName("mainwindow")
container.setContentsMargins(100, 100, 100, 100)
self.setCentralWidget(container)
self.setStyleSheet(stylesheet)
self.setWindowTitle("Neehack")
widget = QWidget()
widget.setObjectName("scanelecontainer")
widget.setAutoFillBackground(True)
lay = QVBoxLayout(container)
lay.addWidget(widget)
effect = QGraphicsDropShadowEffect(
offset=QPoint(3, 3), blurRadius=25, color=QColor("#1a1a1a")
)
widget.setGraphicsEffect(effect)
widget.setStyleSheet(scanelestylesheet)
scanstuscon = QWidget()
scanstuscon.setObjectName("scanstuscon")
scanstuscon.setAutoFillBackground(False)
scanstuscon.setStyleSheet(scanstusconstylesheet)
# 20% = 20/(20 + 80)
lay = QVBoxLayout(widget)
lay.addWidget(scanstuscon, stretch=20)
lay.addStretch(80)
self.resize(1200, 800)

How to apply stylesheets to menu of QPushButton

How do I apply css style sheet to a menu of QPushButton. I have made numerous attempts but Nothing seems to work. I found a similar discussion here
Here is my attempt:
from PyQt5 import QtWidgets
import sys
_style = """
#ButtonMenu > QPushButton{
background-color: blue;
}
/* #ButtonMenu > QPushButton::menu{
background-color: blue;
}*/
QMenu{
background-color: red;
}
/* #ButtonMenu > QMenu{
background-color: red;
}
*/
"""
class ButtonMenu(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super(ButtonMenu, self).__init__(*args, **kwargs)
self.setObjectName("ButtonMenu")
layout = QtWidgets.QVBoxLayout()
button = QtWidgets.QPushButton()
menu = QtWidgets.QMenu()
menu.addAction("hello")
menu.addAction("world")
button.setMenu(menu)
layout.addWidget(button)
self.setLayout(layout)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
win = ButtonMenu()
win.setStyleSheet(_style)
win.show()
sys.exit(app.exec_())
Try it:
import sys
from PyQt5 import QtWidgets, QtGui
class ButtonMenu(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super(ButtonMenu, self).__init__(*args, **kwargs)
self.setObjectName("ButtonMenu")
button = QtWidgets.QPushButton()
menu = QtWidgets.QMenu()
menu.addAction("hello")
menu.addAction("world")
button.setMenu(menu)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(button)
_style = """
#ButtonMenu {
background-color: blue;
}
QPushButton {
background-color: #f0f;
}
QMenu {
background: #ff0;
border: 2px solid red;
border-radius: 2px;
}
QMenu::item {
color: green;
font-size: 22px;
}
QMenu::item:selected {
background: #0ff;
color: red;
}
"""
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setStyleSheet(_style) # +
win = ButtonMenu()
# win.setStyleSheet(_style)
win.show()
sys.exit(app.exec_())

QSplitter() doesn't treat a QScrollArea() and QFrame() equally

1. Problem explained
I'm experimenting with Qt's QSplitter() widget. I've built a very simple sample project in PyQt5 showing a QSplitter() encapsulating a QScrollArea() on the left and a QFrame() on the right:
I've given both the QScrollArea() and QFrame() equal stretch factors, but the QSplitter() doesn't treat them equally. The QScrollArea() always gets most space. I have no idea why.
Minimal, Reproducible Example
Simply copy-paste the code below in a .py script and run it. I've got Python 3.7 with PyQt5 running on a Windows 10 machine.
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class Scroller(QScrollArea):
'''
The Scroller(), will be first widget in the Splitter().
'''
def __init__(self):
super().__init__()
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
self.setStyleSheet("""
QScrollArea {
background-color:#fce94f;
border-color:#c4a000;
padding: 0px 0px 0px 0px;
margin: 0px 0px 0px 0px;
}
""")
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
# 1. FRAME
self.__frm = QFrame()
self.__frm.setStyleSheet("QFrame { background: #ff25292d; border: none; }")
self.__frm.setMinimumHeight(100)
# 2. LAYOUT
self.__lyt = QVBoxLayout()
self.__frm.setLayout(self.__lyt)
# 3. SELF
self.setWidget(self.__frm)
self.setWidgetResizable(True)
return
class Frame(QFrame):
'''
The Frame(), will be second widget in the Splitter()
'''
def __init__(self):
super().__init__()
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
# 1. FRAME
self.setStyleSheet("""
QFrame {
background-color:#fcaf3e;
border-color:#ce5c00;
padding: 0px 0px 0px 0px;
margin: 0px 0px 0px 0px;
}
""")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__lyt.setSpacing(0)
self.__lyt.setContentsMargins(10, 10, 10, 10)
self.setLayout(self.__lyt)
return
class Splitter(QSplitter):
'''
The Splitter().
'''
def __init__(self, widg1, widg2):
super().__init__()
self.setOrientation(Qt.Horizontal)
self.addWidget(widg1)
self.addWidget(widg2)
self.setStretchFactor(0, 5)
self.setStretchFactor(1, 5)
return
def createHandle(self):
return QSplitterHandle(self.orientation(), self)
class CustomMainWindow(QMainWindow):
'''
CustomMainWindow(), a QMainWindow() to start the whole setup.
'''
def __init__(self):
super().__init__()
self.setGeometry(100, 100, 600, 300)
self.setWindowTitle("QSPLITTER TEST")
# 1. OUTER FRAME
self.__frm = QFrame()
self.__frm.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.__frm.setStyleSheet("""
QFrame {
background-color: #eeeeec;
border-color: #2e3436;
}
""")
self.__lyt = QVBoxLayout()
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.show()
# 2. WIDGETS TO BE PUT IN SPLITTER
self.__widg1 = Scroller()
self.__widg2 = Frame()
# 3. SPLITTER
self.__splitter = Splitter(self.__widg1, self.__widg2)
self.__lyt.addWidget(self.__splitter)
return
if __name__== '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Plastique'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
QSplitter not only takes the stretch factor as a reference, it also takes into account the sizeHint(). If the following is added:
# ...
# 3. SPLITTER
self.__splitter = Splitter(self.__widg1, self.__widg2)
self.__lyt.addWidget(self.__splitter)
print(self.__widg1.sizeHint(), self.__widg2.sizeHint())
return
You get the following:
PyQt5.QtCore.QSize(38, 22) PyQt5.QtCore.QSize(20, 20)
Where we see that the QScrollArea has a greater width in the sizeHint() than the QFrame, and that explains why the observed behavior.
The solution is to establish the same width of sizeHint(), that is, not depend on what it contains.
class Scroller(QScrollArea):
# ...
def sizeHint(self):
s = super().sizeHint()
s.setWidth(20) # same width
return s
class Frame(QFrame):
# ...
def sizeHint(self):
s = super().sizeHint()
s.setWidth(20) # same width
return s
# ...
Output:

Setting combo box's scroll area border/background color in PyQt5

I'm having trouble getting the drop down of a QComboBox to have the same color all around. When I click on my combo box, this appears
I do not want the white border color that appears to be part of the scroller of this drop down. However, I can't figure out what this white border belongs to! Is it the QAbstractScrollArea of the QComboBox? Is it the QListView? Is it the QScrollArea, QScroller or QScrollBar? I've tried setting background colors/border colors for all of these properties but to no avail. The following is a stripped down version of my app so that you can just copy and paste this into python and have it run (unfortunately I really couldn't shorten it any further, so sorry for how long it is!)
import sys
import os
import urllib.request
from PyQt5.QtWidgets import QApplication, QComboBox, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QPixmap, QIcon
class MainWindow(QMainWindow):
def __init__(self, app):
super().__init__()
self.vlayout = QVBoxLayout()
self.main_widget = QWidget()
self.init_combobox()
self.main_widget.setLayout(self.vlayout)
self.setCentralWidget(self.main_widget)
self.show()
def init_combobox(self):
data_solid = urllib.request.urlopen('https://i.imgur.com/fbrdSkv.png').read()
pixmap_solid = QPixmap()
pixmap_solid.loadFromData(data_solid)
data_dashed = urllib.request.urlopen('https://i.imgur.com/gI9oHKm.png').read()
pixmap_dashed = QPixmap()
pixmap_dashed.loadFromData(data_dashed)
data_dotted = urllib.request.urlopen('https://i.imgur.com/AAu4TrX.png').read()
pixmap_dotted = QPixmap()
pixmap_dotted.loadFromData(data_dotted)
cbox = QComboBox()
cbox.setObjectName('linestylecbox')
cbox.setFixedSize(75, 25)
cbox.addItem(QIcon(pixmap_solid), '')
cbox.addItem(QIcon(pixmap_dashed), '')
cbox.addItem(QIcon(pixmap_dotted), '')
cbox.setIconSize(QSize(75, 25))
cbox.setContentsMargins(0, 0, 50, 0)
cbox.setStyleSheet('''
QComboBox#linestylecbox
{
background-color: black;
color: black;
font: 10px Lucida Sans;
border: 0px solid black;
margin: 0px;
}
QComboBox#linestylecbox::drop-down
{
border: 0px;
border-top: 0px;
border-color: black;
background-color: black;
font: 10px Lucida Sans;
}
QComboBox#linestylecbox QListView
{
background-color: black;
color: black;
}
''')
self.vlayout.addWidget(cbox)
if __name__ == '__main__':
app = QApplication(sys.argv)
mw = MainWindow(app)
sys.exit(app.exec_())

PyQt4 - Applying a stylesheet on an object which inherits from QWidget

I am having an issue with PyQt4. I have a class which inherits from QWidget. This class uses a layout to store a QLabel and a QLineEdit. Here is the code:
class SearchBar(QtGui.QWidget):
def __init__(self, parent=None):
super(SearchBar, self).__init__(parent)
self.setStyleSheet(SEARCHBAR_STYLE)
layout = QtGui.QHBoxLayout()
layout.setSpacing(0)
layout.setMargin(0)
layout.addStrut(SEARCHAR_HEIGHT)
lbl_notification = QtGui.QLabel('Hi')
lbl_notification.setStyleSheet(SEARCHBAR_NOTIFICATION_STYLE)
layout.addSpacing(10)
layout.addWidget(lbl_notification)
searchbox = QLineEdit('Search')
layout.addStretch()
layout.addWidget(searchbox)
layout.addSpacing(10)
self.setLayout(layout)
and here is the stylesheet:
SEARCHBAR_STYLE = """
QWidget {
background: #424a7d;
}
.QWidget {
border: 1px solid grey;
}
QLabel {
border-top: 1px solid grey;
border-bottom: 1px solid grey;
}
"""
Now, my problem is that the stylesheet does not apply the way I would like it to. It only applies on my QLabel when the border should be around the whole object:
When I had a function creating my search bar as a QWidget, it worked perfectly, but now that I changed that to a class it does not work. What am I doing wrong?
EDIT: I am trying to achieve this:
EDIT 2: The previous code, before I change it to a class, was this:
def create_bar():
layout = QtGui.QHBoxLayout()
layout.setSpacing(0)
layout.setMargin(0)
layout.addStrut(SEARCHAR_HEIGHT)
lbl_notification = QtGui.QLabel('Hi')
lbl_notification.setStyleSheet(SEARCHBAR_NOTIFICATION_STYLE)
layout.addSpacing(10)
layout.addWidget(lbl_notification)
search_bar = QtGui.QLineEdit('Search')
search_bar.setMinimumSize(200, 25)
search_bar.setMaximumSize(200, 25)
search_bar.setStyleSheet(SEARCHBOX_STYLE)
layout.addStretch()
layout.addWidget(search_bar)
layout.addSpacing(10)
widget = QtGui.QWidget()
widget.setStyleSheet(SEARCHBAR_STYLE)
widget.setLayout(layout)
return widget
Change the base class of SearchBar from QWidget to QFrame, or alternatively implement a style sheet aware paintEvent:
def paintEvent(self, event):
opt = QStyleOption()
opt.initFrom(self)
painter = QPainter(self)
self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)
Then change the style sheet to
SEARCHBAR_STYLE = """
SearchBar {
background: #424a7d;
border: 1px solid grey;
}
"""

Categories

Resources