我正在编写文本编辑器并使用Qt进行GUI.我是Qt的菜鸟,我很难做到这一点.
我需要在QPlainTextEdit的第80列画一条线,但我真的不知道怎么做.我正在使用QPainter,但我无法正确使用它,有什么帮助吗?
Rei*_*ica 10
这是我怎么做的.诚然,这并非完全无足轻重.确定第80列位置的输入是:
80 x浮点的平均字符宽度.使用整数值会将舍入误差放大80倍.因此使用QFontMetricsF
.
滚动条引起的偏移来自contentOffset()
.使用它会很糟糕horizontalScrollbar()->value()
.后者目前有效,但依赖于特定于实现的细节.QPlainTextEdit恰好将滚动条值映射到像素 - 谁知道它明天是否会改变.它没有记录,因此属于未指明的行为.
在QTextDocument
实现了自己的利润率,通过提供documentMargin()
.
另一个陷阱:你必须viewport()
在任何衍生出来的类中绘画QAbstractScrollArea
- 并且QPlainTextEdit
这样做.如果你不这样做,你paintEvent
就变成了无操作.它已被记录,但您必须足够聪明才能真正查看文档.我认为它是API的一个坏角落,可以做出意想不到的事情.在其他任何一个paintEvent
,你只需创建QPainter p
或QPainter p(this)
它的工作.
注意:这是经过测试的可编译代码.
//main.cpp
#include <cmath>
#include <QtWidgets>
class Edit : public QPlainTextEdit
{
public:
Edit(QWidget * parent = 0) : QPlainTextEdit(parent) {}
protected:
void paintEvent(QPaintEvent * ev)
{
QPlainTextEdit::paintEvent(ev);
const QRect rect = ev->rect();
const QFont font = currentCharFormat().font();
int x80 = round(QFontMetricsF(font).averageCharWidth() * 80.0)
+ contentOffset().x()
+ document()->documentMargin();
QPainter p(viewport());
p.setPen(QPen("gray"));
p.drawLine(x80, rect.top(), x80, rect.bottom());
qDebug() << x80 << contentOffset() << document()->documentMargin() << font << endl;
}
};
static QString filler()
{
QString str;
for (char c = '0'; c < '9'; ++ c) {
str.append(QString(10, c));
}
return str;
}
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
Edit ed;
QTextCharFormat fmt = ed.currentCharFormat();
fmt.setFontFamily("courier");
fmt.setFontFixedPitch(true);
ed.setCurrentCharFormat(fmt);
ed.setLineWrapMode(QPlainTextEdit::NoWrap);
qDebug() << fmt.font() << endl;
ed.setPlainText(filler());
ed.show();
app.exec();
}
#include "main.moc"
Run Code Online (Sandbox Code Playgroud)