c++ - 在 QPlainTextEdit 的第 80 列画一条线

标签 c++ qt qt4

我正在编写文本编辑器并使用 Qt 作为 GUI。我是 Qt 的菜鸟,我在做这件事时遇到了麻烦。

我需要在 QPlainTextEdit 的第 80 列画一条线,但我真的不知道该怎么做。我正在使用 QPainter,但我无法正确使用它,有什么帮助吗?

最佳答案

这是我的做法。诚然,这并非完全微不足道。确定第 80 列位置的输入是:

  1. 80 x 浮点平均字符宽度。使用整数值会将舍入误差放大 80 倍。因此请使用 QFontMetricsF

  2. 滚动条的偏移量来自contentOffset()。使用 horizo​​ntalScrollbar()->value() 会很糟糕。后者目前有效,但依赖于特定于实现的细节。 QPlainTextEdit 碰巧将滚动条值映射到像素——谁知道它明天是否会改变。它没有记录,因此属于未指定的行为。

  3. QTextDocument 实现了自己的边距,可通过 documentMargin() 获得。

另一个陷阱:您必须在派生自 QAbstractScrollArea 的任何类中的 viewport() 上绘画——而 QPlainTextEdit 就是这样做的。如果不这样做,您的 paintEvent 将成为空操作。它已记录在案,但您必须足够聪明才能真正查看文档。我认为这是一个糟糕的 API 极端情况,会做一些意想不到的事情。在所有其他 paintEvent 中,您只需创建 QPainter pQPainter 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"

关于c++ - 在 QPlainTextEdit 的第 80 列画一条线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11019519/

相关文章:

QT新手: Add action handler for multiple objects of same type

c++ - Qt绘制垂直布局

c++ - 奇怪的 static_cast 把戏?

qt - 如何在QT中自定义ListView

qt4 - Qt - Windows 7 基本主题下禁用 QPushButton 的样式表

qt - 如何在QML中动态添加组件?

c++ - 确定 C++ 文件中的事件 qmake 配置

c++ - 这是 Visual C++ 2010 中的错误,还是我遗漏了什么?

c++ - 我的 QTreeWidgetIcons 在哪里?

c++ - 使用 std::find 这种方式的正确性