3

テキスト エディタを作成し、GUI に Qt を使用しています。私はQtの初心者で、これを行うのに苦労しています。

QPlainTextEdit の列 80 に線を引く必要がありますが、その方法が本当にわかりません。QPainter を使用していますが、うまくいきません。

4

1 に答える 1

12

これが私がそれを行う方法です。確かに、それは完全に些細なことではありません。80 番目の列の位置を決定するための入力は次のとおりです。

  1. 80 x 浮動小数点の平均文字幅。整数値を使用すると、丸め誤差が 80 倍に拡大されます。したがって、 を使用しますQFontMetricsF

  2. スクロールバーによるオフセットはcontentOffset(). 使い方が悪いhorizontalScrollbar()->value()。後者は現在動作しますが、実装固有の詳細に依存しています。QPlainTextEdit はたまたまスクロールバーの値をピクセルにマップします。明日変更されないかどうかは誰にもわかりません。文書化されていないため、不特定の動作に該当します。

  3. QTextDocument独自のマージンを実装しており、 経由で利用できますdocumentMargin()

もう 1 つの落とし穴: --viewport()から派生するすべてのクラスで をペイントする必要があり、そうします。そうしないと、ノーオペレーションになります。文書化されていますが、実際に文書を調べるには十分に賢くなければなりません。予想外のことをする API の悪いケースだと思います。他のすべてのでは、 orを作成するだけで機能します。QAbstractScrollAreaQPlainTextEditpaintEventpaintEventQPainter 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"
于 2012-06-13T19:40:28.070 に答える