How to make label text to be outlined (for better visibility on transparent Widget) and to be fit into label (as per function setWordWrap (True)? There are examples of how to do one or another, but never both.
Basic example of static label text on transparent widget is:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Application(QWidget):
def __init__(self):
super().__init__()
screen_size = QWidget.screen(self).size()
screen_width = screen_size.width()
screen_height = screen_size.height()
widget_width = screen_width * 0.30
self.setGeometry(100, 100, widget_width, screen_height)
self.move(screen_width - widget_width, 0)
self.setAttribute(Qt.WA_TransparentForMouseEvents)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
| Qt.CustomizeWindowHint | Qt.Window)
l1 = QLabel(self)
l1.setWordWrap(True)
l1.setGeometry(0, 0, widget_width, screen_height)
l1.setFont(QFont('Arial', 22))
l1.setStyleSheet('color:rgb(0,255,0)')
l1.setText('Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello')
def render_the_app():
app = QApplication(sys.argv)
window = Application()
window.setAttribute(Qt.WA_TranslucentBackground)
window.show()
app.exec_()
render_the_app()
This code example will render green color text that is "Hello Hello..." and renders as: wrap text example on transparent widget:
Using a painter path is a fine solution, but it doesn't allow finer control on the contents, especially considering that a text-based widget should also provide correct size hints and, possibly, allow word wrapping.
On the other hand, QTextDocument , which is used by any QWidget subclass that uses text (sometimes publicly, like QTextEdit, others internally, like QLabel), provides the outline feature, so a possible solution is to create a class that partially mimics a QLabel, providing correct size hints and word wrapping.
class Test(QtWidgets.QWidget):
_outlinePen = _alignment = None
def __init__(self, text='', parent=None, **kwargs):
super().__init__(parent)
self.doc = QtGui.QTextDocument()
self._reference = self.doc.clone()
self.doc.contentsChanged.connect(self._rebuildReference)
self._text = text
self._outlineColor = QtGui.QColor(kwargs.get('outlineColor'))
self._outlineWidth = kwargs.get('outlineWidth', 0)
if text:
self.doc.setPlainText(text)
self.updateContents()
def _rebuildReference(self):
self._reference = self.doc.clone()
def updateContents(self):
cursor = QtGui.QTextCursor(self.doc)
cursor.select(cursor.Document)
blockFmt = cursor.blockFormat()
blockFmt.setAlignment(self.alignment())
cursor.setBlockFormat(blockFmt)
charFmt = cursor.charFormat()
charFmt.setFont(self.font())
outlinePen = self.outlinePen()
if outlinePen:
charFmt.setTextOutline(outlinePen)
cursor.setCharFormat(charFmt)
self.updateGeometry()
self.adjustSize()
def text(self):
return self._text
def setText(self, text):
if self._text == text:
return
self.doc.setPlainText(text)
self.updateContents()
def outlinePen(self):
if isinstance(self._outlineColor, QtGui.QColor) and self._outlineColor.isValid():
pen = QtGui.QPen(self._outlineColor)
pen.setWidthF(self._outlineWidth or self.fontMetrics().lineWidth() * .25)
return pen
def setOutlinePen(self, pen):
self._outlineColor = pen.brush().color()
self._outlineWidth = pen.widthF()
self.updateContents()
def outlineColor(self):
return self._outlineColor
def setOutlineColor(self, color):
if self._outlineColor != color:
self._outlineColor = color
self.updateContents()
def outlineWidth(self):
return self._outlineWidth
def setOutlineWidth(self, width):
if self._outlineWidth != width:
self._outlineWidth = width
self.updateContents()
def alignment(self):
alignment = self._alignment
if not isinstance(alignment, (QtCore.Qt.Alignment, QtCore.Qt.AlignmentFlag)):
alignment = QtCore.Qt.AlignTop
if self.layoutDirection() == QtCore.Qt.LeftToRight:
alignment |= QtCore.Qt.AlignLeft
else:
alignment |= QtCore.Qt.AlignRight
return alignment
def setAlignment(self, alignment):
if self._alignment != alignment:
self._alignment = alignment
self.updateContents()
def changeEvent(self, event):
if event.type() == event.FontChange:
self.updateContents()
def sizeHint(self):
if self.isVisible():
doc = self._reference
doc.setTextWidth(self.width())
else:
doc = self.doc
return doc.size().toSize()
def paintEvent(self, event):
qp = QtGui.QPainter(self)
self._reference.setTextWidth(self.width())
self._reference.drawContents(qp, QtCore.QRectF(self.rect()))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.