【问题标题】:QLabel "break" word if too longQLabel“中断”字如果太长
【发布时间】:2020-12-14 15:03:20
【问题描述】:

如果QLabel 单词太长,有没有办法让这些单词中断?我见过

q_label->setWordWrap(true)

但它适用于空格,但如果单个单词太长,则会溢出...
我想要类似word-break: break-all 的东西用于网络开发

我也见过QTextDocument,但它不允许有固定的宽度和不固定的高度

【问题讨论】:

  • QTextDocument 不允许有固定的宽度和不固定的高度 QWidget::setSizePolicy 怎么样?
  • 您可以创建自己的标签,并在paintEvent() 方法中,使用drawText()Qt::TextWrapAnywhere 标志

标签: c++ string qt widget label


【解决方案1】:

据我所知,没有现成的方法可以自动将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) 允许在一行的任意位置换行。

【讨论】:

    【解决方案2】:

    您可以有一个函数,每次单词大于标签的最大大小时添加一个空格。如果您想限制字符数中的字长,这应该可以:

    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 的默认自动换行器包裹的文本的标签大小(这也需要重新实现它以计算换行次数)。您应该确保标签足够大以容纳所有文本。

    【讨论】:

      【解决方案3】:

      TextWrapAnywhere QLabel

      子类QLabel 并实现paintEvent,您可以在drawItemText 时将文本对齐方式设置为TextWrapAnywhere

      请参阅this question 以获取 pyqt5 中的示例。

      【讨论】:

      • 我已经在 C++ 中实现了这一点:style()-&gt;drawItemText(&amp;p, rect(), Qt::AlignLeft | Qt::TextWrapAnywhere, palette(), true, text()); 但是它似乎没有任何改变
      • 我还没有实现c++,但是只要pyqt可以工作它就应该可以工作。
      【解决方案4】:

      Qt 仅支持不包含word-breakHTML 子集。否则解决方案将非常简单。

      但是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
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-01
        • 1970-01-01
        • 2019-05-31
        • 2017-02-24
        • 1970-01-01
        相关资源
        最近更新 更多