是否有方法使QLabel
在单词太长时自动换行?我看过一些...
q_label->setWordWrap(true)
虽然有空格时它能正常工作,但如果单词太长,就会出现溢出的问题...
我想要像 word-break: break-all
这样的 web 开发方案
我也看过 QTextDocument
,但它不允许设置固定宽度和非固定高度
零宽空格
from PySide2 import QtWidgets
app = QtWidgets.QApplication()
label = QtWidgets.QLabel()
text = "TheBrownFoxJumpedOverTheLazyDog"
label.setWordWrap(True)
label.setText("\u200b".join(text)) # The magic is here.
label.show()
app.exec_()
QLabel
from PySide2 import QtWidgets
class HumanLabel(QtWidgets.QLabel):
def __init__(self, text: str = "", parent: QtWidgets.QWidget = None):
super().__init__("\u200b".join(text), parent)
self.setWordWrap(True)
def setText(self, arg__1: str) -> None:
super().setText("\u200b".join(arg__1))
def text(self) -> str:
return super().text().replace("\u200b", "")
app = QtWidgets.QApplication()
text = "TheBrownFoxJumpedOverTheLazyDog"
label = HumanLabel(text)
assert label.text() == text
label.show()
app.exec_()
Qt
只支持不包含 word-break
的 HTML
子集。或者解决方案将非常简单。
但是,也可以使用 QTextBrowser
来解决问题。它继承自 QTextEdit
,并处于只读模式。在 QTextBrowser
中的 QTextDocument
就能解决问题。
QTextBrowser tb = new QTextBrowser(parent);
QTextOption opt;
opt.setWrapMode(QTextOption::WrapAnywhere); // like word-break: break-all
tb->document()->setDefaultTextOption(opt);
tb->setStyleSheet("border: none;"); // no border
tb->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); // no vertical scroller bar
tb->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); // no horizontal scroller bar
QLabel
。QLabel::setWordWrap()
正常工作。QLabel *pLabel = new QLabel(this);
pLabel->setText("first line\nsecond line\nthird line\n");
pLabel->setWordWrap(true);
你也可以使用QTextDocument。它的setDefaultTextOption
方法允许你设置QTextOption。而QTextOption::setWrapMode(QTextOption::WrapAnywhere)
则允许在一行的任何位置换行。
void wrapLabelByCharCount(QLabel *label, int characterCount)
{
QString text = label->text();
int wordLength = 0;
bool insideWord = false;
QFontMetrics fontMetrics(label->font());
for (int i = 0; i < text.length(); i++)
{
if (text[i] == ' ' || text[i] == '\t' || text[i] == '\n')
insideWord = false;
else
{
if (!insideWord)
{
insideWord = true;
wordLength = 0;
}
++wordLength;
}
if (wordLength > characterCount)
{
text = text.left(i) + "\n" + text.right(text.length() - i);
label->setFixedHeight(label->height() + fontMetrics.height());
insideWord = false;
}
}
label->setText(text);
}
如果你想根据固定像素宽度来换行,那么你应该使用这个:
void wrapLabelByTextSize(QLabel *label, int widthInPixels)
{
QString text = label->text();
QString word = "";
bool insideWord = false;
QFontMetrics fontMetrics(label->font());
for (int i = 0; i < text.length(); i++)
{
if (text[i] == ' ' || text[i] == '\t' || text[i] == '\n')
insideWord = false;
else
{
if (!insideWord)
{
insideWord = true;
word = "";
}
word += text[i];
}
if (fontMetrics.horizontalAdvance(word) > widthInPixels)
{
text = text.left(i) + "\n" + text.right(text.length() - i);
label->setFixedHeight(label->height() + fontMetrics.height());
insideWord = false;
}
}
label->setText(text);
}
以下是如何使用它们的一些示例:
q_label->setWordWrap(true); //required for this to work
wrapLabelByCharCount(q_label, 15); // wraps all words that have more than 15 characters
wrapLabelByTextSize(q_label, q_label->width()); // wraps words that exceed the width of your label (this is probably the one you want)
wrapLabelByTextSize(q_label, 25); // wraps words that exceed 25 pixels
编辑: 需要注意的是,这些函数不会调整QLabel默认字词换行器包装的文本标签大小(这也需要重新实现它以计算换行数)。您应该确保标签足够大以适应所有文本。
继承 QLabel
并实现 paintEvent
,在其中使用 drawItemText
时将文本对齐方式设置为 TextWrapAnywhere
。
请参考 这个问题 中的 pyqt5 示例。
style()->drawItemText(&p, rect(), Qt::AlignLeft | Qt::TextWrapAnywhere, palette(), true, text());
但是它似乎没有改变任何东西。 - Jachdich
paintEvent()
方法中使用drawText()
和Qt::TextWrapAnywhere
标志。 - thibsc