如何在qt中覆盖标签宽度?

22

我只需要知道如何在QTextEdit中更改标签大小。 我的Google和stackoverflow搜索结果为空。 提前致谢。

(仅供参考,不要直接复制)


1
tabStopWidth 属性怎么样?http://doc.qt.digia.com/qt/qtextedit.html#tabStopWidth-prop - fasked
我误操作拒绝了建议的编辑,我认为它是有效的。 - Al.G.
5个回答

41
如果你想使用 QTextEdit 创建一个源代码编辑器,你应该先分配一个固定宽度(等宽)字体。这可以确保所有字符具有相同的宽度:
QFont font;
font.setFamily("Courier");
font.setStyleHint(QFont::Monospace);
font.setFixedPitch(true);
font.setPointSize(10);

QTextEdit* editor = new QTextEdit();
editor->setFont(font);

如果您想将制表符宽度设置为特定数量的空格,就像文本编辑器中通常所做的那样,请使用 QFontMetrics 计算一个空格在像素中的大小:
const int tabStop = 4;  // 4 characters

QFontMetrics metrics(font);
editor->setTabStopWidth(tabStop * metrics.width(' '));

很遗憾,自Qt 5.10以来,setTabStopWidth已经过时,请参见https://doc.qt.io/archives/qt-5.10/qtextedit-obsolete.html。 - Patrizio Bekerle
1
@PatrizioBekerle - 看起来它只是被重命名为 tabStopDistance?请参见 https://doc.qt.io/archives/qt-5.10/qtextedit.html#tabStopDistance-prop - Ferdinand Beyer
是的,@ferdinand-beyer,看起来是这样。 - Patrizio Bekerle
字符的宽度不再使用,您可以放心使用maxWidth(),因为宽度是统一的。 - Shefeto

8
< p > QTextEdit::tabStopWidth 属性可能会解决你的问题(请参见此处有关文档...)

该属性可能有助于解决您的问题,它在此处进行了详细介绍。

1
感谢你的回复,为了尝试它,我将TabStopWidth设置为40,这改变了我的制表符大小。但是这相当于11个空格字符和5个a字符。为什么所有字符大小都不同?我希望我的编辑器像源代码编辑器一样工作。我错过了什么? - Barış Akkurt
使用等宽字体,如Courier New,则所有字符的宽度相同。 - JonathanK

6

虽然有关如何设置制表位宽度的问题已经得到回答;计算正确的制表符宽度(以像素为单位)仍然是一个开放的问题。

自从Qt 5.10以来,QTextEdit::tabStopWidth被标记为过时,而引入了QTextEdit::tabStopDistancetabStopWidth是整数,而tabStopDistancedouble

为什么这么复杂?

n * QFontMetrics :: width(' ')设置为制表位宽度会带来麻烦,因为font_metrics.width返回整数。即使您有一个等宽标准字体,单个字符的宽度实际上也不是整数,因此QFontMetrics :: width 返回的是不准确的测量值。 如果您比较字符串........|\t\t\t\t|(\ t = tab,n = 2)的外观,您会发现管道未对齐。插入的制表符越多,情况就会变得更糟。

解决方案

您可以执行@Ferdinand Beyer提出的操作,但它会略微改变字体。我还必须调整他的方法才能使其正常工作。但是,有一种更简单的方法,利用现在可以使用双精度设置tabStopDistance

static constexpr int tab_width_char = 2;
m_text_edit->setFont(QFont("Courier", 12));
const auto font_metrics = m_text_edit->fontMetrics();

static constexpr int big_number = 1000; // arbitrary big number.
const QString test_string(" ");

// compute the size of a char in double-precision
const int single_char_width = font_metrics.width(test_string);
const int many_char_width = font_metrics.width(test_string.repeated(big_number));
const double single_char_width_double = many_char_width / double(big_number);

// set the tab stop with double precision
m_text_edit->setTabStopDistance(tab_width_char * single_char_width_double);

如果Qt提供了一种以double类型获取单个字符宽度的方法,这将会简单得多。

1
在至少Qt 5.15.2中,我不得不将font_metrics.width更改为font_metrics.horizontalAdvance,除此之外,这个解决方案是唯一对我有效的! - foddex

5

尽管@Ferdinand Beyer的解决方案可以在某些系统上工作,但通常不能保证字体具有整数度量。例如,在我Linux配置下,12pt DejaVu Sans Mono的字符宽度为9.625。我发现的最佳解决方案是添加一些字母间距以实现像素完美对齐。

int tabstop = 4;

QFontMetricsF fm (ui->textEdit->font());
auto stopWidth = tabstop * fm.width(' ');
auto letterSpacing = (ceil(stopWidth) - stopWidth) / tabstop;

auto font = ui->textEdit->font();
font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing);
ui->textEdit->setFont(font);

ui->textEdit->setTabStopWidth(ceil(stopWidth));

4

计算一个空格和多个空格的乘积并不总是精确的(在macOS、Monaco字体下测试),这可能是因为实际字符串中字符之间存在一些间隙。

更好的解决方案是测量包含tabStop空格的字符串的长度:

const int tabStop = 4;  // 4 characters

QString spaces;
for (int i = 0; i < tabStop; ++i) {
    spaces += " ";
}

QFontMetrics metrics(font);
editor->setTabStopWidth(metrics.width(spaces));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接