pyqt5 QPushButtone hover style when it's flat=True - python

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.

Related

Python/PySide6: Apply different style to sub class

Cant figure out the solution of the problem.
The style of the sub class is identical to the base class:
import sys
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from PySide6.QtCore import *
class MyLabel(QLabel):
def __init__(self, pText: str) -> None:
super().__init__()
self.setText(pText)
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.setFixedWidth(200)
self.setFixedHeight(200)
layout = QVBoxLayout(self)
self.widget = QLabel("QLabel")
layout.addWidget(self.widget)
self.mywidget = MyLabel("MyLabel")
layout.addWidget(self.mywidget)
self.setLayout(layout)
stylesheet = ("""
MyLabel {
border: 20px solid black;
}
QLabel {
border: 20px solid red;
}
"""
)
self.setStyleSheet(stylesheet)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec())
The expectation is to have the inherited label in a different color.
Eg MyLabel should be black. QLabel should be red.
Thanks for help
Had a typo in the shown py-script:
self.widget and self.mywidget were instances of MyLabel class.
This is fixed.
Figured out that it depends on the sequence of styles:
This sequence does not work:
stylesheet = ("""
MyLabel {
border: 20px solid black;
}
QLabel {
border: 20px solid red;
}
"""
)
This sequence works:
stylesheet = ("""
QLabel {
border: 20px solid red;
}
MyLabel {
border: 20px solid black;
}
"""
)

Hover Effect for Two or More Widgets at a same time?

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_())

PyQt5 customize style of QAction in menuBar

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()

How do I change the color of the text in a menu bar item in PyQt5?

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_())

Changing widget's highlight color in PyQt5

I've figured out how to change the background color of PyQt5 widgets using setStyleSheet() but I cannot find how to change their highlight color. I am 100% sure this option should be available as in tkinter.
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.create_widgets()
def create_widgets(self):
b1 = QPushButton(parent=self, text='Button')
color_1 = 'red'
color_2 = 'blue'
b1.setStyleSheet('QWidget {background-color: %s}' % color_1)
#b1.setStyleSheet('QWidget {highlight-color: %s}' % color_2) does not work
b1.resize(150,50)
b1.move(100,100)
self.setGeometry(300,200, 400, 400)
self.show()
if __name__ == '__main__':
app = QApplication([])
ex = Example()
sys.exit(app.exec_())
Any help is greatly appreciated!
To customize QPushButton you can use the following style sheet:
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
class Example(QWidget):
def __init__(self):
super().__init__()
self.create_widgets()
def create_widgets(self):
b1 = QPushButton(parent=self, text='Button')
b1.setGeometry(150,150, 100, 100)
style = '''
QWidget {
background-color: coral;
}
QPushButton {
background-color: #006325;
font-size: 20px;
color: white;
min-width: 100px;
max-width: 100px;
min-height: 100px;
max-height: 100px;
border-radius: 50px;
border-width: 1px;
border-color: #ae32a0;
border-style: solid;
}
QPushButton:hover {
background-color: #328930;
color: yellow;
}
QPushButton:pressed {
background-color: #80c342;
color: red;
}
'''
if __name__ == '__main__':
app = QApplication([])
app.setStyleSheet(style) # <---
ex = Example()
ex.setGeometry(300,200, 400, 400)
ex.setWindowTitle("QPushButton - style sheet")
ex.show()
sys.exit(app.exec_())

Categories