我正在編寫一個文本編輯器,並在GUI中使用Qt。我是Qt的noob,我很難做到這一點。在QPlainTextEdit的第80列畫一條線
我需要在QPlainTextEdit的第80列畫一條線,但我真的不知道如何。我正在使用QPainter,但我無法做到,沒有任何幫助?
我正在編寫一個文本編輯器,並在GUI中使用Qt。我是Qt的noob,我很難做到這一點。在QPlainTextEdit的第80列畫一條線
我需要在QPlainTextEdit的第80列畫一條線,但我真的不知道如何。我正在使用QPainter,但我無法做到,沒有任何幫助?
下面是我該怎麼做。毫無疑問,這並非微不足道。確定第80列位置的輸入是:
80 x浮點中的平均字符寬度。使用整數值會將舍入誤差放大80倍。因此使用QFontMetricsF
。
由滾動條引起的偏移量來自contentOffset()
。使用horizontalScrollbar()->value()
會很糟糕。後者目前可行,但依賴於實現特定的細節。 QPlainTextEdit恰好將滾動條值映射到像素 - 誰知道它明天是否會改變。它沒有記錄,因此屬於未指定的行爲。
QTextDocument
實施自己的保證金,可通過documentMargin()
獲得。
另一個缺陷:你必須從QAbstractScrollArea
派生的任何類搽viewport()
- 和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"