我希望Qt.TextWrapAnywhere用于布局中的 QLabel。
我按照此指令進行操作。我的代碼也相同,以提供最少的代碼
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QStyleOption, QVBoxLayout, QWidget, QStyle
class SuperQLabel(QLabel):
def __init__(self, *args, **kwargs):
super(SuperQLabel, self).__init__(*args, **kwargs)
self.textalignment = Qt.AlignLeft | Qt.TextWrapAnywhere
self.isTextLabel = True
self.align = None
def paintEvent(self, event):
opt = QStyleOption()
opt.initFrom(self)
painter = QPainter(self)
self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)
self.style().drawItemText(painter, self.rect(),
self.textalignment, self.palette(), True, self.text())
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.resize(100, 200)
self.label = QLabel()
self.label.setWordWrap(True)
self.label.setText("11111111111111111111\n2222222211111111")
self.slabel = SuperQLabel()
self.slabel.setMinimumWidth(10)
self.slabel.setText("111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
self.centralwidget = QWidget()
self.setCentralWidget(self.centralwidget)
self.mainlayout = QVBoxLayout()
self.mainlayout.addWidget(self.label)
self.mainlayout.addWidget(self.slabel)
self.centralwidget.setLayout(self.mainlayout)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
我更改了一點代碼self.slabel.setMinimumWidth(10)否則根據寬度調整標簽大小將不起作用。
它可以根據寬度完美地包裹文本。但問題是當高度被認為是self.label = QLabel()正常 QLabel 會根據布局的內容自動調整高度。
例如,如果我添加一個帶有文本的\n,這意味著 Qlabel 必須顯示 2 行。
但是使用這個新的自定義標簽,例如self.slabel = SuperQLabel() 包裝是好的,只要布局中有高度空間。我想我必須使用setminimumHeight()但不知道如何在自定義包裝后獲得適當的高度。
uj5u.com熱心網友回復:
經過一番研究,我成功修復了它。有個竅門
這是有/沒有表情符號的完全回應??
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter,QFontMetrics,QFont
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QStyleOption, QVBoxLayout, QWidget, QStyle
import math
class SuperQLabel(QLabel):
def __init__(self, *args, **kwargs):
super(SuperQLabel, self).__init__(*args, **kwargs)
self.textalignment = Qt.AlignLeft | Qt.TextWrapAnywhere
self.isTextLabel = True
self.align = None
def paintEvent(self, event):
opt = QStyleOption()
opt.initFrom(self)
painter = QPainter(self)
self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)
self.style().drawItemText(painter, self.rect(),
self.textalignment, self.palette(), True, self.text())
fm=QFontMetrics(self.font())
#To get unicode in Text if using Emoji(Optional)
string_unicode = self.text().encode("unicode_escape").decode()
##To remove emoji/unicode from text while calculating
string_encode = self.text().encode("ascii", "ignore")
string_decode = string_encode.decode()
#If Unicode/Emoji is Used
if string_unicode.count("\\U0001") > 0:
height=fm.boundingRect(self.rect(),Qt.TextWordWrap,string_decode).height() 1
# 1 is varrying according to Different font .SO set different value and test.
else:
height=fm.boundingRect(self.rect(),Qt.TextWordWrap,string_decode).height()
row=math.ceil(fm.horizontalAdvance(self.text())/self.width())
self.setMinimumHeight(row*height)
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.resize(100, 200)
self.label = QLabel()
self.label.setWordWrap(True)
self.label.setStyleSheet("background:red;")
self.label.setText("11111111111111111111\n2222222211111111")
self.emoji_font = QFont("Segoe UI Emoji",15,0,False)
self.emoji_font.setBold(True)
self.slabel = SuperQLabel()
self.slabel.setMinimumWidth(10)
self.slabel.setStyleSheet("background:green;")
self.slabel.setFont(self.emoji_font)
########### Plain Text ######################
# self.slabel.setText("111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
#################### Or Using Emoji ############
self.slabel.setText("111111111111111111??111ABCDDWAEQQ111111111111??1111111111??111111wqewqgdfgdfhyhtyhy1111111??111111111111??1111111111111111111")
self.centralwidget = QWidget()
self.setCentralWidget(self.centralwidget)
self.mainlayout = QVBoxLayout()
self.mainlayout.addWidget(self.label)
self.mainlayout.addWidget(self.slabel)
self.centralwidget.setLayout(self.mainlayout)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
uj5u.com熱心網友回復:
只要標簽顯示在滾動區域中(不會對頂層布局產生問題),更好的解決方案是使用 QTextEdit 子類,配置如下:
readOnly必須為真;- 滾動條被禁用;
- 垂直尺寸政策必須是
Preferred(而不是Expanding); - 兩者都
minimumSizeHint()應該sizeHint()使用內部 QTextDocument 來回傳適當的高度,并具有最小的默認寬度; - 必須觸發大小或內容的任何更改,
updateGeometry()以便父布局知道提示已更改并且可以再次計算幾何圖形; - 提示必須包括滾動區域的可能裝飾(這是一個 QFrame);
paintEvent()由于 QTextDocument 提供的功能,這允許避免覆寫,并提供更好和更容易的大小機制實作,同時將遞回的可能性降至可接受的水平。
class WrapLabel(QtWidgets.QTextEdit):
def __init__(self, text=''):
super().__init__(text)
self.setStyleSheet('''
WrapLabel {
border: 1px outset palette(dark);
border-radius: 8px;
background: palette(light);
}
''')
self.setReadOnly(True)
self.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
QtWidgets.QSizePolicy.Maximum)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.textChanged.connect(self.updateGeometry)
def minimumSizeHint(self):
doc = self.document().clone()
doc.setTextWidth(self.viewport().width())
height = doc.size().height()
height = self.frameWidth() * 2
return QtCore.QSize(50, height)
def sizeHint(self):
return self.minimumSizeHint()
def resizeEvent(self, event):
super().resizeEvent(event)
self.updateGeometry()
class ChatTest(QtWidgets.QScrollArea):
def __init__(self):
super().__init__()
self.messages = []
container = QtWidgets.QWidget()
self.setWidget(container)
self.setWidgetResizable(True)
layout = QtWidgets.QVBoxLayout(container)
layout.addStretch()
self.resize(480, 360)
for i in range(1, 11):
QtCore.QTimer.singleShot(1000 * i, lambda:
self.addMessage('1' * randrange(100, 250)))
def addMessage(self, text):
self.widget().layout().addWidget(WrapLabel(text))
QtCore.QTimer.singleShot(0, self.scrollToBottom)
def scrollToBottom(self):
QtWidgets.QApplication.processEvents()
self.verticalScrollBar().setValue(
self.verticalScrollBar().maximum())
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/418537.html
標籤:
上一篇:從資源檔案匯入QML模塊
