QPainter再指定区域内绘制文本并自动换行

在Qt编程中,自定义绘制控件时可能会遇到文本超出绘制区域的问题。文章介绍了三种实现文本换行的方法:使用drawText函数配合Qt::TextWordWrap标志,通过QTextOption设置换行模式,以及利用QTextDocument和QTextLayout进行布局。这些方法允许在固定宽度区域内自适应地显示文本,支持不同类型的换行策略。
摘要由CSDN通过智能技术生成

在自定义绘制控件时,经常遇到文本超过绘制区域的情况,容易想到的办法显示部分文字和换行,一下介绍如何实现换行

方式一

//drawText(const QRectF &rectangle, int flags, const QString &text, QRectF *boundingRect = nullptr)
/*
	The flags argument is a bitwise OR of the following flags:
    Qt::AlignLeft
    Qt::AlignRight
    Qt::AlignHCenter
    Qt::AlignJustify
    Qt::AlignTop
    Qt::AlignBottom
    Qt::AlignVCenter
    Qt::AlignCenter
    Qt::TextDontClip
    Qt::TextSingleLine
    Qt::TextExpandTabs
    Qt::TextShowMnemonic
    Qt::TextWordWrap
    Qt::TextIncludeTrailingSpaces
*/
//适合固定区域文字自动换行模式
//eg:
QRectF rect(0,0,300,300);
QString text = "this is text";
painter->drawText(rect, Qt::TextWordWrap, text);

方式二

/*
void drawText(const QRectF &rectangle, const QString &text, const QTextOption &option = QTextOption())
这种方式可以指定文本换行的位置,比如任意位置换行,或者单词末尾换行

QTextOption::NoWrap
QTextOption::WordWrap
QTextOption::ManualWrap
QTextOption::WrapAnywhere
QTextOption::WrapAtWordBoundaryOrAnywhere

*/
//eg:
QRectF rect(0,0,300,300);
QString text = "this is text";
QTextOption option;
option.setWrapMode(QTextOption::WrapAnywhere)
painter->drawText(rect, Qt::TextWordWrap, option);

方式三

QPainter painter(this);
QTextOption option;
option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); // 设置自动换行模式
QString text = "This is a long text that needs to be broken into multiple lines.";
QTextDocument doc;
doc.setDefaultTextOption(option);
doc.setPlainText(text);
QTextLayout layout(doc);
layout.beginLayout();
QTextLine line = layout.createLine();
int y = 0;
while (line.isValid()) 
{
    line.setLineWidth(200);
    line.setPosition(QPointF(0, y));
    y += line.height();
    line = layout.createLine();
}
layout.endLayout();

layout.draw(&painter, QPointF(0, 0));

扩展

根据给定的文字长度,以固定的宽度区域,自适应高度绘制文本

//先计算出文本的宽度,和指定宽度比较,小于自定宽度直接绘制,否则需要计算换几行,指定高度
QPainter painter(this);
QFontMetrics metrics(painter.font());
QString text = "This is a long text that needs to be broken into multiple lines";
int textwidth = metrics.horizontalAdvance(text);	//获取文本的宽度
int rectWidth = 300;	//指定绘制宽度
int height = metrics.height();	//获取字体高度
if(textwidth <= rectwidth)
{//能够容纳,直接绘制
    QRect rect(0,0,rectwidth,height);
    painter.drawText(rect,Qt::AlignCenter,text);
}
else
{
    //计算需要显示几行
    int index = 0;
    QString temp = text;
    while(true)
    {
        auto temp1 = metrics.elidedText(temp,Qt::ElideRight,rectwidth);	//截断文字
        if(temp1.isEmpty()) break;
        
        index++;
        temp1 = temp1.remove("…");	//删除截断符号
        temp = temp.remove(temp1);
    }
    
    int _height = index*height;
    QRect rect(0,0,rectwidth,_height);
    QTextOption option;
    option.setWrapMode(QTextOption::WrapAnywhere)
    painter->drawText(rect, Qt::TextWordWrap, option);
    
}

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在QPainter中实现自动换行功能,可以使用QFontMetrics类来计算文本的宽度和高度,然后根据所需的宽度和高度进行换行。以下是一个简单的示例代码: ```python from PyQt5.QtGui import QPainter, QFontMetrics from PyQt5.QtCore import Qt # ... def paintEvent(self, event): painter = QPainter(self) font = painter.font() font.setPointSize(14) painter.setFont(font) text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla facilisi. Sed eget mi nec mi porta dictum. Aliquam erat volutpat. Donec eleifend nulla eget nulla malesuada convallis. Sed quis diam eget dolor auctor aliquam ut eget eros. Sed eget neque porttitor, cursus nulla facilisis, gravida lectus. Sed vel pharetra purus. Sed in sollicitudin mi, id interdum velit. Vivamus gravida dapibus dolor, nec facilisis lacus imperdiet eget. Maecenas sed turpis sed velit iaculis bibendum. Duis feugiat augue in sodales pulvinar. In non mi euismod, laoreet nibh sit amet, vestibulum sapien. Fusce ac tristique turpis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed in nulla id neque consequat ultricies. Nulla facilisi." rect = self.geometry() top_margin = 20 bottom_margin = 20 left_margin = 20 right_margin = 20 fm = QFontMetrics(font) y = top_margin for line in text.split('\n'): x = left_margin for word in line.split(): word_width = fm.width(word) if x + word_width > rect.width() - right_margin: x = left_margin y += fm.height() painter.drawText(x, y, word) x += word_width + fm.width(' ') y += fm.height() painter.end() ``` 在此示例中,我们首先设置了字体大小为14,并将其应用于绘图器。然后,我们定义了要绘制的多行文本。接下来,我们定义了绘制区域的边距,并使用QFontMetrics类计算每个单词的宽度和高度。最后,我们使用嵌套的循环来逐个单词地绘制文本,并在达到绘制区域的右侧时换行。 请注意,此示例仅处理空格分隔的单词,而不考虑其他标点符号。要处理其他标点符号,需要对代码进行修改。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值