- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在编写一个 Visual Basic IDE,我需要将行号添加到 QTextEdit 并突出显示当前行。我找到了这个 tutorial ,但它是用 Java 编写的,我用 C++ 编写我的项目。
最佳答案
我知道 Qt 教程推荐使用 QPlainTextEdit
来实现文本编辑器,而且这个问题(除了标题中提到的)比处理(absolutely ) 带有 QTextEdit
小部件,但我成功实现了该行为(行号 + 当前行号突出显示),我认为这可能对一些真正想继续前进的人(如我)有所帮助使用 Rich Text
小部件,并希望分享我的实现(远非完美 - 编码速度相当快......)。
LineNumberArea.h :(同“QPlainTextEdit”教程)
class LineNumberArea : public QWidget
{
Q_OBJECT
public:
LineNumberArea(QTextEdit *editor);
QSize sizeHint() const;
protected:
void paintEvent(QPaintEvent *event);
private:
QTextEdit *codeEditor;
};
LineNumberArea.cpp :(与“QPlainTextEdit”教程相同)
LineNumberArea::LineNumberArea(QTextEdit *editor) : QWidget(editor) {
codeEditor = editor;
}
QSize LineNumberArea::sizeHint() const {
return QSize(((QTextEditHighlighter *)codeEditor)->lineNumberAreaWidth(), 0);
}
void LineNumberArea::paintEvent(QPaintEvent *event) {
((QTextEditHighlighter *)codeEditor)->lineNumberAreaPaintEvent(event);
}
>> qtextedithighlighter.h:
class QTextEditHighlighter : public QTextEdit
{
Q_OBJECT
public:
explicit QTextEditHighlighter(QWidget *parent = 0);
int getFirstVisibleBlockId();
void lineNumberAreaPaintEvent(QPaintEvent *event);
int lineNumberAreaWidth();
signals:
public slots:
void resizeEvent(QResizeEvent *e);
private slots:
void updateLineNumberAreaWidth(int newBlockCount);
void updateLineNumberArea(QRectF /*rect_f*/);
void updateLineNumberArea(int /*slider_pos*/);
void updateLineNumberArea();
private:
QWidget *lineNumberArea;
};
>> qtextedithighlighter.cpp:
#include "qtextedithighlighter.h"
QTextEditHighlighter::QTextEditHighlighter(QWidget *parent) :
QTextEdit(parent)
{
// Line numbers
lineNumberArea = new LineNumberArea(this);
///
connect(this->document(), SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
connect(this->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateLineNumberArea/*_2*/(int)));
connect(this, SIGNAL(textChanged()), this, SLOT(updateLineNumberArea()));
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateLineNumberArea()));
///
updateLineNumberAreaWidth(0);
}
int QTextEditHighlighter::lineNumberAreaWidth()
{
int digits = 1;
int max = qMax(1, this->document()->blockCount());
while (max >= 10) {
max /= 10;
++digits;
}
int space = 13 + fontMetrics().width(QLatin1Char('9')) * (digits);
return space;
}
void QTextEditHighlighter::updateLineNumberAreaWidth(int /* newBlockCount */)
{
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}
void QTextEditHighlighter::updateLineNumberArea(QRectF /*rect_f*/)
{
QTextEditHighlighter::updateLineNumberArea();
}
void QTextEditHighlighter::updateLineNumberArea(int /*slider_pos*/)
{
QTextEditHighlighter::updateLineNumberArea();
}
void QTextEditHighlighter::updateLineNumberArea()
{
/*
* When the signal is emitted, the sliderPosition has been adjusted according to the action,
* but the value has not yet been propagated (meaning the valueChanged() signal was not yet emitted),
* and the visual display has not been updated. In slots connected to this signal you can thus safely
* adjust any action by calling setSliderPosition() yourself, based on both the action and the
* slider's value.
*/
// Make sure the sliderPosition triggers one last time the valueChanged() signal with the actual value !!!!
this->verticalScrollBar()->setSliderPosition(this->verticalScrollBar()->sliderPosition());
// Since "QTextEdit" does not have an "updateRequest(...)" signal, we chose
// to grab the imformations from "sliderPosition()" and "contentsRect()".
// See the necessary connections used (Class constructor implementation part).
QRect rect = this->contentsRect();
lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
updateLineNumberAreaWidth(0);
//----------
int dy = this->verticalScrollBar()->sliderPosition();
if (dy > -1) {
lineNumberArea->scroll(0, dy);
}
// Addjust slider to alway see the number of the currently being edited line...
int first_block_id = getFirstVisibleBlockId();
if (first_block_id == 0 || this->textCursor().block().blockNumber() == first_block_id-1)
this->verticalScrollBar()->setSliderPosition(dy-this->document()->documentMargin());
// // Snap to first line (TODO...)
// if (first_block_id > 0)
// {
// int slider_pos = this->verticalScrollBar()->sliderPosition();
// int prev_block_height = (int) this->document()->documentLayout()->blockBoundingRect(this->document()->findBlockByNumber(first_block_id-1)).height();
// if (dy <= this->document()->documentMargin() + prev_block_height)
// this->verticalScrollBar()->setSliderPosition(slider_pos - (this->document()->documentMargin() + prev_block_height));
// }
}
void QTextEditHighlighter::resizeEvent(QResizeEvent *e)
{
QTextEdit::resizeEvent(e);
QRect cr = this->contentsRect();
lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}
int QTextEditHighlighter::getFirstVisibleBlockId()
{
// Detect the first block for which bounding rect - once translated
// in absolute coordinated - is contained by the editor's text area
// Costly way of doing but since "blockBoundingGeometry(...)" doesn't
// exists for "QTextEdit"...
QTextCursor curs = QTextCursor(this->document());
curs.movePosition(QTextCursor::Start);
for(int i=0; i < this->document()->blockCount(); ++i)
{
QTextBlock block = curs.block();
QRect r1 = this->viewport()->geometry();
QRect r2 = this->document()->documentLayout()->blockBoundingRect(block).translated(
this->viewport()->geometry().x(), this->viewport()->geometry().y() - (
this->verticalScrollBar()->sliderPosition()
) ).toRect();
if (r1.contains(r2, true)) { return i; }
curs.movePosition(QTextCursor::NextBlock);
}
return 0;
}
void QTextEditHighlighter::lineNumberAreaPaintEvent(QPaintEvent *event)
{
this->verticalScrollBar()->setSliderPosition(this->verticalScrollBar()->sliderPosition());
QPainter painter(lineNumberArea);
painter.fillRect(event->rect(), Qt::lightGray);
int blockNumber = this->getFirstVisibleBlockId();
QTextBlock block = this->document()->findBlockByNumber(blockNumber);
QTextBlock prev_block = (blockNumber > 0) ? this->document()->findBlockByNumber(blockNumber-1) : block;
int translate_y = (blockNumber > 0) ? -this->verticalScrollBar()->sliderPosition() : 0;
int top = this->viewport()->geometry().top();
// Adjust text position according to the previous "non entirely visible" block
// if applicable. Also takes in consideration the document's margin offset.
int additional_margin;
if (blockNumber == 0)
// Simply adjust to document's margin
additional_margin = (int) this->document()->documentMargin() -1 - this->verticalScrollBar()->sliderPosition();
else
// Getting the height of the visible part of the previous "non entirely visible" block
additional_margin = (int) this->document()->documentLayout()->blockBoundingRect(prev_block)
.translated(0, translate_y).intersect(this->viewport()->geometry()).height();
// Shift the starting point
top += additional_margin;
int bottom = top + (int) this->document()->documentLayout()->blockBoundingRect(block).height();
QColor col_1(90, 255, 30); // Current line (custom green)
QColor col_0(120, 120, 120); // Other lines (custom darkgrey)
// Draw the numbers (displaying the current line number in green)
while (block.isValid() && top <= event->rect().bottom()) {
if (block.isVisible() && bottom >= event->rect().top()) {
QString number = QString::number(blockNumber + 1);
painter.setPen(QColor(120, 120, 120));
painter.setPen((this->textCursor().blockNumber() == blockNumber) ? col_1 : col_0);
painter.drawText(-5, top,
lineNumberArea->width(), fontMetrics().height(),
Qt::AlignRight, number);
}
block = block.next();
top = bottom;
bottom = top + (int) this->document()->documentLayout()->blockBoundingRect(block).height();
++blockNumber;
}
}
希望这可以帮助...
关于c++ - 如何将行号添加到 QTextEdit?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2443358/
我使用 QTextEdit 的子类显示一些富文本内容. 一些编辑器——尤其是代码编辑器和 IDE 提供了一种可能性,可以一直滚动到最后一行之外,直到最后一行到达 View 的顶部。 我希望能够使用 Q
我已经放弃了让它跑得更快的实际尝试。 我最大的问题是,当我插入 html 时,应用程序会变慢到爬行。我有一个进度条,我正在调用 QCoreApplication.processEvents() (顺便
好吧,我正在做一个IDE系统。基本上,一切正常。虽然,但我有一个问题。 “QTextEdit”类没有用于自动完成的成员“setCompleter”。对? 那么,是否有一些类支持它,包括所有 QText
当我创建一个默认的 QTextEdit 小部件时,它会出现在默认的 Windows 样式边框中。我不想要这个边框,所以我试着把它关掉。我该怎么做? 我使用的是相当旧版本的 Qt (3.2.3)。 最佳
我想用QTextEdit (在只读模式下)显示可点击的超链接,我曾经这样做 QTextEdit *textEdit = new QTextEdit; QTextCursor cursor(textEd
我有一个仅从 qtextedit 返回选定文本的函数。我需要获取纯文本,但此函数返回带有一些控制字符的文本。 例如:函数textEdit->textCursor().selectedText()返回:
为QTextEdit设置文本: te->setPlainText(“Something”) ; te->adjustSize(); 应该只环绕“Something”,而不是QTextEdit正在扩展到
QTextEdit t; t.setHtml(" ");显示带有锐音符的小“a”而不是不间断空格。这种情况仅发生在 Windows 上,而不是 Linux 或 FreeBSD 上。可能是什么
感谢code,它帮助我解决了很多显示文本的问题。但是有一个符号困扰着我: [2K 但看起来像这样:在此处输入图片描述 据我理解ANSI中的该符号的意思-删除该行并在其位置写入新信息。我该怎么办? 最佳
文本编辑器:Sublime Text 3 Python 版本:3.6 UTF-8 PyQt5 我正在 PyQt5 中制作一个记事本,并且我正在制作一个能够在行之间导航的选项,当然,我需要移动文本编辑器
所以我尝试使用 shell 输出(实时)更新 QTextEdit: txtDirb = QTextEdit() dirb_command = "dirb" + " " + url p = subpro
我正在尝试尾随文件并将其连续输出到QTextEdit框。但是,我的子进程和输出位于多进程中。这是我的代码: shouldRun = True wMain = QtGui.QWidget() textb
我想升级我的日志部分以适应日志记录模块。 我的应用程序已经相当先进,并且使用 PySide 进行 GUI。我想设置处理程序来生成不同的日志文件,但也想设置一个写入 QTextEdit 类似控制台的小部
我的程序应该: 从 QLineEdits 收集一些输入; 将其转换为QString; 将其添加到一些常量的QString中; 单击按钮时在 QTextEdit 中输出全部内容。 下面是程序的简化模型。
我有一个带有某种日志查看器的应用程序,它需要能够呈现实时插入其中的格式化日志记录。 我在 Qt 中写这篇文章,到目前为止,我使用 QTextEdit 来呈现文本,使用一些 html 标签对其进行了美化
所以问题是如何从另一个表单设置 textEdit 的值? 最佳答案 您有两个选择,或者您可以简单地从另一个表单中的函数调用其中一个 setText 函数,如下所示: otherForm->setPla
我的 QMainWindow 上有一个 QTextEdit。我已经覆盖了我的主窗口 keyPressEvent 方法并在其中放置了一些热键处理程序(即:Ctrl+J、Ctrl+K)。这些热键对应用程序
是否有任何用于创建文本完成器的 QT 类(如果我键入“hel”,它会自动用“lo”完成单词)?抱歉用词不好,我不知道如何更好地描述它。 最佳答案 有 QCompleter,但默认情况下仅适用于 QLi
我目前正在开发一个文本编辑器,我想创建一个缩写系统。我的意思是,例如,当您编写 html5 然后按 tab 键时,例如您展开这样的代码: ... 也许我使用了错误的关键字,
我正在考虑使用 QTextEdit作为类似控制台的 IO 元素(用于串行数据)。这种方法的问题是(用户)输入和(通信)输出是混合的,它们可能不同步。 要检测新的用户输入,可以存储和比较某些输入事件的
我是一名优秀的程序员,十分优秀!