Использование HTML тегов в названии кнопки PyQt6
В своем проекте на PyQt6 я с легкостью пользовался HTML тегами в таких элементах, как QLabel:
l = QLabel('<span>Something</span><b>text</b>')
Но я никогда не пробовал применять их в других. Сейчас мне понадобилось вставить теги в название QPushButton. Я попробовал тоже самое:
btn = QPushButton('<span>text</span>')
Но здесь уже они экранируются, и я пока что не нагуглил каким образом можно обойти эту проблему. Есть ли какое нибудь решение?
Ответы (2 шт):
Все таки нашел решение через переопределение класса QPushButton. Фишка заключается в том, что внутри можно создать экземпляры QLabel и использовать их вместо родного тайтла кнопки (понадобится создать компоновщик). Также нужно переопределить метод setText() и sizeHint():
class RichTextPushButton(QPushButton):
def __init__(self, parent=None, text=None):
if parent is not None:
super().__init__(parent)
else:
super().__init__()
self.__lbl = QLabel(self)
if text is not None:
self.__lbl.setText(text)
self.__lyt = QHBoxLayout()
self.__lyt.setContentsMargins(0, 0, 0, 0)
self.__lyt.setSpacing(0)
self.setLayout(self.__lyt)
self.__lbl.setAttribute(Qt.WA_TranslucentBackground)
self.__lbl.setAttribute(Qt.WA_TransparentForMouseEvents)
self.__lbl.setSizePolicy(
QSizePolicy.Expanding,
QSizePolicy.Expanding,
)
self.__lbl.setTextFormat(Qt.RichText)
self.__lyt.addWidget(self.__lbl)
return
def setText(self, text):
self.__lbl.setText(text)
self.updateGeometry()
return
def sizeHint(self):
s = QPushButton.sizeHint(self)
w = self.__lbl.sizeHint()
s.setWidth(w.width())
s.setHeight(w.height())
return s
Вместе с тем убираем фон и ивенты связанные с мышью на лэйблах.
PS: Стоит отметить, что тем не менее форматирование в этом случае заметно более ограничено, чем в нативном HTML и CSS. К примеру нельзя прикрутить к span'у border-radius. Он просто на него не реагирует. Но все же это лучше, чем ничего.
Можно отрисовать руками в paintEvent - сначала нарисовать пустую кнопку, а потом в ней richtext
from PyQt5.QtWidgets import *
from PyQt5 import QtGui, QtCore
import sys
class QMyPushButton(QPushButton):
def __init__(self, parent):
super().__init__(parent)
def paintEvent(self, event):
# Текст запомним и обнулим, чтобы отрисовать кнопку без текста
text = self.text()
self.setText('')
# оригинальный paintEvent отрисует кнопку без текста
super().paintEvent(event)
self.setText(text)
# отрисовываем RichText
qp = QtGui.QPainter()
qp.begin(self)
# центрирование надписи придется вам реализовывать самостоятельно
top_left = QtCore.QPoint(10, 15)
qp.drawStaticText(top_left, QtGui.QStaticText(text))
qp.end()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.central_widget = QWidget(self)
self.setCentralWidget(self.central_widget)
self.btn = QMyPushButton(self.central_widget)
self.btn.resize(150, 50)
self.btn.move(30,20)
self.btn.setText('<i>hello</i> <font color="red">amazing</font> <b>world</b>')
if __name__ == '__main__':
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())