I am having a Custom widget that contains a QLabel and a custom label(MessageLabel). I would like to know how I can add css styles to the QLabel inside the custom widget.
Here is my code.
from PyQt5 import QtWidgets, QtCore
import sys
_style = """
#MessageLabel{
background-color: rgba(196, 195, 192, 100);
color: white;
padding: 10px;
border-radius: 5px 5px 30px 5px;
selection-color: black;
selection-background-color: white;
}
#MessageDisplayWidget #InfoLabel{
color: red;
background-color: blue;
}
"""
class MessageLabel(QtWidgets.QLabel):
def __init__(self, *args, **kwargs):
super(MessageLabel, self).__init__(*args, **kwargs)
self.setObjectName("MessageLabel")
font = self.font()
font.setPointSize(12)
self.setFont(font)
self.setMinimumWidth(100)
self.setText("Hello World")
class MessageDisplayWidget(QtWidgets.QWidget):
def __init__(self):
super(MessageDisplayWidget, self).__init__()
self.message_box_frame = QtWidgets.QFrame()
self.vBoxLayout = QtWidgets.QVBoxLayout(self.message_box_frame)
self.vBoxLayout.setSpacing(0)
self.setLayout(self.vBoxLayout)
self.message_lbl_layout = QtWidgets.QVBoxLayout()
self.more_options_layout = QtWidgets.QHBoxLayout()
self.more_options_layout.setContentsMargins(0, 0, 0, 0)
self.vBoxLayout.addLayout(self.message_lbl_layout, 1)
self.vBoxLayout.addLayout(self.more_options_layout, 0)
self.message_text = MessageLabel() # this is a custom label
self.info_label = QtWidgets.QLabel("time") # this is the label I want to change
self.info_label.setObjectName("InfoLabel")
self.info_label.setFixedHeight(30)
self.message_lbl_layout.addWidget(self.message_text)
self.more_options_layout.addWidget(self.info_label)
self.more_options_layout.setStretch(0, 1)
self.more_options_layout.setAlignment(self.info_label, QtCore.Qt.AlignRight)
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
win = MessageDisplayWidget()
win.setStyleSheet(_style)
win.show()
sys.exit(app.exec_())
"""
QVboxlayout
|
- QVboxLayout(Message), QVboxLayout(MoreOptions)
| |
MessageLabel InfoLabel
"""
As shown in the above image I would like to add css style to time label
Related
How to make a Hover effect for Two or More QLabels at a time? For Example, In my code, I need to hover effect for Lbl1 and Lbl2 at a time. ( Either Mouse enter into a QLabel 1 or QLabel 2, both QLabels will take a Hover Effect)
from PyQt5 import QtWidgets
class Hover_Multiple(QtWidgets.QWidget):
def __init__(self):
super(). __init__()
self.setWindowTitle("Hover Effects")
self.lbl1 = QtWidgets.QLabel("Python")
self.lbl1.setFixedSize(100,50)
self.lbl1.setStyleSheet(mystyle())
self.lbl2 = QtWidgets.QLabel("PyQt5")
self.lbl2.setStyleSheet(mystyle())
self.lbl2.setFixedSize(100,50)
self.hbox = QtWidgets.QHBoxLayout()
self.hbox.addStretch()
self.hbox.addWidget(self.lbl1)
self.hbox.addWidget(self.lbl2)
self.hbox.addStretch()
self.hbox.setSpacing(0)
self.hbox.setContentsMargins(0,0,0,0)
self.setLayout(self.hbox)
def mystyle():
return"""
QLabel
{
background-color:lightgreen;
min-height : 25%; min-width : 40%;
border:0px solid;border-color:red;
text-align:centre ;font-size :10pt; font-family:Trebuchet MS; color:Black; padding : 2px;
}
QLabel::hover
{
background-color: red;
color :white;
}
"""
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainwindow = Hover_Multiple()
mainwindow.show()
sys.exit(app.exec_())
A possible solution is to use a qproperty that serves as a flag to change the painting, and that qproperty must be changed in the widgets when some widget is triggered by the QEvent::HoverEnter and QEvent::HoverLeave events and that can be done using an eventfilter.
from PyQt5 import QtCore, QtWidgets
class HoverHelper(QtCore.QObject):
def __init__(self, parent=None):
super().__init__(parent)
self._widgets = []
#property
def widgets(self):
return self._widgets
def add_widget(self, widget):
if not isinstance(widget, QtWidgets.QWidget):
raise TypeError(f"{widget} must be QWidget object")
widget.installEventFilter(self)
widget.setAttribute(QtCore.Qt.WA_Hover)
self.widgets.append(widget)
def eventFilter(self, obj, event):
if obj in self.widgets:
if event.type() == QtCore.QEvent.HoverEnter:
self.change_property(True)
elif event.type() == QtCore.QEvent.HoverLeave:
self.change_property(False)
return super().eventFilter(obj, event)
def change_property(self, hovered):
for widget in self.widgets:
widget.setProperty("hovered", hovered)
widget.style().polish(widget)
class Hover_Multiple(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Hover Effects")
self.setStyleSheet(style_sheet())
self.lbl1 = QtWidgets.QLabel("Python")
self.lbl1.setFixedSize(100, 50)
self.lbl2 = QtWidgets.QLabel("PyQt5")
self.lbl2.setFixedSize(100, 50)
lay = QtWidgets.QHBoxLayout(self)
lay.addStretch()
lay.addWidget(self.lbl1)
lay.addWidget(self.lbl2)
lay.addStretch()
lay.setSpacing(0)
lay.setContentsMargins(0, 0, 0, 0)
helper = HoverHelper(self)
helper.add_widget(self.lbl1)
helper.add_widget(self.lbl2)
def style_sheet():
return """
QLabel{
background-color: lightgreen;
min-height: 25%;
min-width: 40%;
border: 0px solid;
border-color: red;
text-align: center;
font-size: 10pt;
font-family: Trebuchet MS;
color: black;
padding: 2px;
}
QLabel[hovered="true"]{
background-color: red;
color: white;
}
"""
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainwindow = Hover_Multiple()
mainwindow.show()
sys.exit(app.exec_())
I want to make a hover style of a QPushButton When it is flat, is it possible?. Seems hover is not showing with flat. If not, how can I make a similar flat style with a QPushButton with hover.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 button - pythonspot.com'
self.left = 10
self.top = 10
self.width = 320
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.button = QPushButton('PyQt5 button', self, flat=True)
self.button.setStyleSheet(""" QPushButton {
background-color: yellow;
}
QPushButton#pushButton:hover {
background-color: blue;
}
QPushButton#pushButton:pressed {
background-color: orange;
}"""
)
self.button.move(100,70)
self.button.clicked.connect(self.on_click)
self.show()
#pyqtSlot()
def on_click(self):
print('PyQt5 button click')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Here is a simple example how to make flat button with hover
self.button = QPushButton('PyQt5 button',self)
self.button.setStyleSheet(open('style.css').read())
And style.css
QPushButton {
padding: 5px;
border-color: black;
border-style: outset;
border-width: 2px;
color: black;
background-color: yellow;
}
QPushButton:hover {
background-color: blue;
}
QPushButton:pressed {
background-color: orange;
}
Link to documentation to read more options.
This question already has an answer here:
How to change QSlider handle width using stylesheet
(1 answer)
Closed 2 years ago.
I'm trying to increase the width of the Qslider handle to make it more user friendly on small screens, but I've only found ways of doing this in C++.
I have tried to implement this in python using the following code, only for it to change the colour of the slider:
self.Zoom.setStyleSheet("""
QSlider::handle:horizontal {
height: 80px;
}
""")
Any advice on how to use QWidget.setStyleSheet() correctly.
A possible solution is to use a QProxyStyle:
from PyQt5 import QtCore, QtWidgets
class SliderProxyStyle(QtWidgets.QProxyStyle):
def pixelMetric(self, metric, option, widget):
if metric == QtWidgets.QStyle.PM_SliderThickness:
return 40
elif metric == QtWidgets.QStyle.PM_SliderLength:
return 40
return super().pixelMetric(metric, option, widget)
class TestWindow(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
style = SliderProxyStyle(self.slider.style())
self.slider.setStyle(style)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.slider)
lay.addStretch()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle("fusion")
w = TestWindow()
w.show()
app.exec_()
Before
After
A possible solution is to use a QSS:
from PyQt5 import QtCore, QtWidgets
class TestWindow(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.slider.setMinimumHeight(70)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.slider)
lay.addStretch()
QSS = """
/* QSlider -------------------------------------- */
QSlider::groove:horizontal {
border-radius: 1px;
height: 3px;
margin: 0px;
background-color: rgb(52, 59, 72);
}
QSlider::groove:horizontal:hover {
background-color: rgb(55, 62, 76);
}
QSlider::handle:horizontal {
background-color: rgb(85, 170, 255);
border: none;
height: 40px;
width: 40px;
margin: -20px 0;
border-radius: 20px;
padding: -20px 0px;
}
QSlider::handle:horizontal:hover {
background-color: rgb(155, 180, 255);
}
QSlider::handle:horizontal:pressed {
background-color: rgb(65, 255, 195);
}
"""
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle("fusion")
app.setStyleSheet(QSS)
w = TestWindow()
w.show()
sys.exit(app.exec_())
I found very similar questions but no reasonable solution for this issue. I would like to change the style/appearance of QActions which are displayed in menus of a QMainWindow menuBar (e.g. change the background color). The purpose is to highlight the currently selected action when navigating through the menu again.
Example:
from PyQt5 import QtWidgets, QtCore
class Window(QtWidgets.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
action1 = QtWidgets.QAction("action1", self)
action2 = QtWidgets.QAction("action2", self)
action1.triggered.connect(self.print_stuff)
action2.triggered.connect(self.print_stuff)
mainMenu = self.menuBar()
mainMenu.setNativeMenuBar(False)
fileMenu = mainMenu.addMenu('Menu1')
fileMenu.addAction(action1)
fileMenu.addAction(action2)
def print_stuff(self):
print('whatever')
def run():
app = QtWidgets.QApplication([])
application = Window()
application.show()
app.exec_()
run()
One could change the StyleSheet of individual menus in the menuBar but I can't change the StyleSheet of QActions since those are not widgets. However, it seems possible to modify the background, since the QActions are e.g. highlighted when they are hovered with the mouse - just like the menus in the menubar. Any ideas?
use QWidgetAction:
from PyQt5 import QtWidgets, QtCore, QtGui
class Window(QtWidgets.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
mainMenu = self.menuBar()
mainMenu.setNativeMenuBar(False)
fileMenu = mainMenu.addMenu('Menu1')
action1 = QtWidgets.QAction("action1", self)
action2 = QtWidgets.QAction("action2", self)
action3 = QtWidgets.QWidgetAction(fileMenu)
l = QtWidgets.QLabel("action3")
l.setStyleSheet("QLabel { background-color : red; padding: 4 4 4 4px;}")
action3.setDefaultWidget(l)
fileMenu.addAction(action1)
fileMenu.addAction(action2)
fileMenu.addAction(action3)
action1.triggered.connect(self.print_stuff)
action2.triggered.connect(self.print_stuff)
action3.triggered.connect(self.print_stuff)
def print_stuff(self):
print('whatever')
def run():
app = QtWidgets.QApplication([])
application = Window()
application.show()
app.exec_()
run()
Result:
Try it:
from PyQt5 import QtWidgets, QtCore, QtGui
class Window(QtWidgets.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
mainMenu = self.menuBar()
mainMenu.setNativeMenuBar(False)
self.fileMenu = mainMenu.addMenu('Menu1')
action1 = QtWidgets.QWidgetAction(self)
self.label1 = QtWidgets.QLabel("action1")
action1.setDefaultWidget(self.label1);
action1.setText('action1')
action2 = QtWidgets.QWidgetAction(self)
self.label2 = QtWidgets.QLabel("action2")
action2.setDefaultWidget(self.label2);
action2.setText('action2')
action3 = QtWidgets.QWidgetAction(self)
self.label3 = QtWidgets.QLabel("action3")
action3.setDefaultWidget(self.label3);
action3.setText('action3')
self.fileMenu.addAction(action1)
self.fileMenu.addAction(action2)
self.fileMenu.addAction(action3)
self.fileMenu.triggered.connect(self.print_stuff) # +++
def print_stuff(self, q):
print('whatever->', q.text() )
self.label1.setStyleSheet("""
QLabel { background-color : #ABABAB; padding: 10px 12px 10px 12px;}
QLabel:hover { background-color: #654321;}
""")
self.label2.setStyleSheet("""
QLabel { background-color : #ABABAB; padding: 10px 12px 10px 12px;}
QLabel:hover { background-color: #654321;}
""")
self.label3.setStyleSheet("""
QLabel { background-color : #ABABAB; padding: 10px 12px 10px 12px;}
QLabel:hover { background-color: #654321;}
""")
if q.text() == 'action1':
self.label1.setStyleSheet("""
QLabel { background-color : red; padding: 10px 12px 10px 12px;}
QLabel:hover { background-color: #C10000;}
""")
elif q.text() == 'action2':
self.label2.setStyleSheet("""
QLabel { background-color : red; padding: 10px 12px 10px 12px;}
QLabel:hover { background-color: #C10000;}
""")
elif q.text() == 'action3':
self.label3.setStyleSheet("""
QLabel { background-color : red; padding: 10px 12px 10px 12px;}
QLabel:hover { background-color: #C10000;}
""")
qss = """
QMenuBar {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 lightgray, stop:1 darkgray);
}
QMenuBar::item {
spacing: 3px;
padding: 2px 10px;
background-color: rgb(210,105,30);
color: rgb(255,255,255);
border-radius: 5px;
}
QMenuBar::item:selected {
background-color: rgb(244,164,96);
}
QMenuBar::item:pressed {
background: rgb(128,0,0);
}
QLabel {
background-color: #ABABAB;
color: rgb(255,255,255);
font: 12px;
padding: 10px 12px 10px 12px;
}
QLabel:hover {
background-color: #654321;
}
"""
def run():
app = QtWidgets.QApplication([])
app.setStyleSheet(qss) # <---
application = Window()
application.show()
app.exec_()
run()
Let's say I have a GUI that has a menu bar.
mainMenu = self.menuBar()
mainMenu.setStyleSheet("""QMenuBar { background-color: rgb(45, 45, 48); }""") #Set the background color of the menu bar to black.
testMenu = mainMenu.addMenu('Test') # I want to change the color of this text.
test_dropButton = QAction('Test', self)
test_dropButton = setShortcut('Ctrl+T')
test_dropButton.triggered.connect(self.close)
testMenu.addActtion(test_dropButton)#add button to drop down menu.
How can I change the color of the text of the individual menu QAction buttons? Would I do it by adding to the style sheet calling the QAction::item rgb(r, g, b) or is there a more efficient way?
Try it:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
qss = """
QMenuBar {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 lightgray, stop:1 darkgray);
}
QMenuBar::item {
spacing: 3px;
padding: 2px 10px;
background-color: rgb(210,105,30);
color: rgb(255,255,255);
border-radius: 5px;
}
QMenuBar::item:selected {
background-color: rgb(244,164,96);
}
QMenuBar::item:pressed {
background: rgb(128,0,0);
}
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
QMenu {
background-color: #ABABAB;
border: 1px solid black;
margin: 2px;
}
QMenu::item {
background-color: transparent;
}
QMenu::item:selected {
background-color: #654321;
color: rgb(255,255,255);
}
"""
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
### vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
mainMenu = self.menuBar()
testMenu = mainMenu.addMenu('mainMenu')
test1_dropButton = QAction('Test 1', self)
testMenu.addAction(test1_dropButton)
test2_dropButton = QAction('Test 2', self)
test2_dropButton.triggered.connect(self.displayImage)
testMenu.addAction(test2_dropButton)
test_dropButton = QAction('Exit', self)
test_dropButton.setShortcut('Ctrl+E')
test_dropButton.triggered.connect(self.close)
testMenu.addAction(test_dropButton)
### ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def initUI(self):
central_widget = QWidget()
self.setCentralWidget(central_widget)
self.layV = QVBoxLayout(central_widget)
def displayImage(self):
pixmap = QPixmap("D:/_Qt/img/pyqt.jpg")
lbl = QLabel(self)
self.layV.addWidget(lbl)
lbl.setPixmap(pixmap.scaled(400, 400, Qt.KeepAspectRatio))
if __name__ == '__main__':
app = QApplication([])
app.setStyleSheet(qss) # <--------------------------------
ex = Example()
ex.setWindowTitle('Style Sheet: QMenuBar, QMenu')
ex.setWindowIcon(QIcon('D:/_Qt/img/py-qt.png'))
ex.resize(420,440)
ex.show()
sys.exit(app.exec_())