• QPlainTextEdit等 自制 文本或者代码 编辑器控件 是如何 自定义 实现的?


    我们会发现这些编辑器控件,都是继承自  QAbstractScrollArea 类,比如 QPlainTextEdit,大名鼎鼎的 QsciScintilla 编辑器控件,小熊猫IDE的 SynEdit 编辑器控件等。

    QAbstractScrollArea是提供一个可以滚动的窗口,里面可以容纳很多子控件。

    文本如何实现显示的呢?

    那就是我们的子类需要重新实现 paintEvent 事件函数。

    void paintEvent(QPaintEvent *event) override;

    这个函数里面需要我们自己定义 QPainter 对象去执行具体的绘制工作,过程如下:

    • 定义一个 QPainter 对象
    • painter->fillRect(AClip,edit->mGutter.color()); 填充一个矩形,应该是为了设置背景色
    • painter->setFont(edit->mGutter.font()); 设置绘制文本的字体
    • painter->setPen(edit->mGutter.activeLineTextColor()); 设置画笔的颜色
    • painter->drawText(string) 绘制出这些文本了

    一个编辑器的区域组成

    同理,画其它区域也是如此,比如画编辑器的边缘margin(有的编辑器也叫做 Gutter),比如显示箭头,断点,行号等。也是通过绘制实现的,而不是直接搞个QWiget并排放置在那儿。具体过程机制如下:

    通过在编辑器内里,创建两个专门管理不同区域坐标的对象(注意:这些对象不是继承自QWidget,因为它们仅仅是用于管理不同区域的坐标范围信息,比如长宽等),比如小熊猫IDE的 SynEdit 编辑器类里就有成员:

    SynGutter mGutter; 其中继承关系【 class SynGutter : public QObject 】

    在绘制的时候,就通过这些对象来实现分别控制绘制的动作了,比如哪些地方该绘制矩形,哪些地方该绘制指定的图片,哪些地方该绘制文本。

    所以,一整个编辑器控件只是一个QWidget,而不是说margins(或者叫做gutter栏,例如行号栏)是一个并排放置的QWidget(当然自制编辑器网上也有人这么干的,行号栏等位置就是放一个qwidget,比如qtcreator的示例项目,还有有人搞的一个QCodeEditor,这两个项目就是这样的,本文结尾会介绍一下这个编辑器)。

    因此,当我们在编辑器中鼠标右键时,我们发现 contextMenuEvent(QContextMenuEvent *event) 函数总是能得到触发,而不管我们右键在行号栏还是文本显示区。但是我们可能希望右键在行号栏,文本显示区时候能区分出来,怎么做呢?只需要判断event->pos的和margin的区域坐标的关系,就能知道有没有右键在margin区了,从而显示不同的菜单。大家可以看我这个博客,对上述两个编辑器的分析 QsciScintilla等编辑器实现不同区域鼠标右键处理方式不同的方法_标biao的博客-CSDN博客

    附录:QPainter类有哪些函数呢?

    void drawPoint(const QPointF &pt); 画点函数
    void drawLine(const QLineF &line); 画线函数
    void drawRect(const QRectF &rect); 画矩形
    drawPixmap                         画图片
    void drawText(const QPointF &p, const QString &s);   画文本
    ...... 等
    

    其它编辑器简单介绍

    1. qtcreator的欢迎页面,搜索一下,就有这个示例工程,左侧行号栏就是一个单独的qwidget。可以参考一下 Code Editor无能为力一天_素默的博客-CSDN博客_codeeditor

     2. 网上有人做了个QCodeEditor类的编辑器(注:这不是qt官方库有的,但是我估计参考了qtcreator源码中的编辑器部分),也挺好看的,但是功能还是太少了,比如自动折叠功能等都不具备的,而且缩放时候,明显卡顿。

    QCodeEditor - Widget for Qt - CodeProject

    QCodeEditor - 基于Qt的代码编辑器_码肥人壮的博客-CSDN博客_qt 代码编辑器

  • 相关阅读:
    Java 变得越来越像 Rust?
    Mysql 45讲学习笔记(十二)MySQL会“抖”一下
    SpringMVC获取请求参数
    机器学习周记(第三十八周:语义分割)2024.5.6~2024.5.12
    服务器断电重启后报XFS文件系统错误 XFS (dm-0)_ Metadata I_O error
    9.2.4 DATETIME类型
    反向代理原理
    如何使用javascript制作一个网页端3D贪吃蛇游戏(附源码及链接)
    12月3日:thinkphp模型与数据库相同的部分
    (八)fastai 目标检测 object detection
  • 原文地址:https://blog.csdn.net/kangkanglhb88008/article/details/126821059