• 编辑器库QsciScintilla的indicator点击没有按键信息的bug解决


    问题描述:

    我正在做IDE(嵌入式系统用的集成开发环境)的代码跳转功能,也就是按下 ctrl+鼠标左键释放 实现一个标识符跳转到 定义/声明 的功能(eclipse,vscode,qtcreator等IDE都具备这个功能)。遇到了这个问题。

        
    首先看我这个博客了解一下信号:QScintilla的信号汇总和解释_我是标同学的博客-CSDN博客
    
    //一个是关联qsci这个封装层的信号
    connect(this, &QsciScintilla::indicatorReleased, this, &EditorCpp::onIndicatorReleased);    
    
    //或者关联qsciBasei这个封装层的信号
    connect(this, &QsciScintillaBase::SCN_INDICATORRELEASE, this, &EditorCpp::onIndicatorReleasedSci); 

    这两个信号传出的参数都是一样的,这里以qsci这个封装层为例,如下:

    void indicatorReleased(int line, int index, Qt::KeyboardModifiers state);

    其中state指明了,我们鼠标点击这个indicator释放鼠标的时候我们按下的ctrl、alt、shift键的状态。但是我运行,始终打印出来的按键都是0???

    但是我实测,关联那个按下信号 void indicatorClicked(int line, int index, Qt::KeyboardModifiers state);就能正确打印出按键信息的。

    查找问题过程:(追踪qsci的源码)

    首先看这个信号发射出来的位置

    因此,我们看到,QsciScintilla的信号,其实就是更底层的 QsciScintillaBase的信号来的。所以,我们需要追踪 SCN_INDICATORRELEASE 这个信号又是怎么来的。


    此时来到了Scintilla这个底层开源库这边了(关于这个库的继承结构,可以看我这个博客:QScintilla学习大全_我是标同学的博客-CSDN博客_qscintilla

    我们可以看到,其实 NotifyParent()这个函数发出的信号,也就是这里就是底层库 Scintilla 和qt的QsciScintilla 的接口处了,被qt全部转为对应的信号了。如果不是用qt进行封装,那么就可能是通过回调函数形式把这个接口暴漏出去了。很明显,qt的信号和槽机制很好用,清晰,灵活。

    继续追踪这个 NotifyIndicatorClick()函数被谁调用,我们发现是 :(一个是鼠标按下,一个是鼠标弹起,这两个函数都会调用到NotifyIndicatorClick()函数,从上面一张图可以看到,是靠第一个参数 true,表示按下,false表示弹起,来区分状态的)

    void Editor::ButtonUpWithModifiers(Point pt, unsigned int curTime, int modifiers)
    void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers)

    原因:

    到这里,其实仍然会传进来按键的状态modifiers的,但是,我们可以看到鼠标弹起这里,直接传入的是0作为ctrl,alt、shift等的按键状态值,导致我们在qt那边程序的槽函数中,打印出来的按键值始终是0,这里终于找到原因了。真是坑啊!!!

    而鼠标按下这个消息,就是正确的传入了按键信息,这就解释了我文章开头说的实测的结果:鼠标按下indicator能检测到ctrl、alt、shift等按键状态的,但是鼠标弹起时,检测到的始终是0了。

    解决方法:

    主要有两个方法:

    1. qt自己是可以获取到按键信息的,自己记录下来使用就行了。推荐用这个方法。
    2. 把这个库这里修改一下,让modifiers变量给传进去。但是如果我们使用QsciScintilla这个dll库来使用的话(看我这个博客 QScintilla如何安装和入门(初学者)_我是标同学的博客-CSDN博客_qscintilla),就还得重新编译这个库,是个麻烦事,所以不推荐这个方法了。

    从下图中可以看出,而另一个样式hostpot触发,人家就是按键状态给带着的。关于hostpot资料可以看这个 https://qscintilla.com/#clickable_text/hotspots

     

    总结:

    在我们用别人的库的时候,其实这些库难免也可能是有bug的,有出现问题的地方的,所以我们最好是把它对应的源码也搞到,这样有些用法上的疑惑,或者遇到问题,我们直接追踪它这个库的源码,就能方便的解决很多问题了。如果仅仅是网上搜索答案,可能别人也没遇到过,所以找不到答案的。

    而且自己去追踪源码这个过程,也是提高我们代码能力(欣赏一下别人的源码的写法),而且最重要的是要具备解决问题的能力(遇到问题不要慌,仔细分析原因,思考解决方法),这正是作为程序员进阶需要具备的能力。

    前几天,qt的事件处理循环过程我一直有些疑惑,网上和官方的资料看了,还是有些疑惑解答不通,所以我自己追踪了qt的源码,看了一下,就搞明白了。可以看我这个博客 qt源码解析1--事件循环原理(重写事件函数,事件过滤器等)_我是标同学的博客-CSDN博客

  • 相关阅读:
    ARM开发(5)ARM的接口技术(串行通信与并行通信,同步串行通信与异步串行通信,波特率,串行通信术语,uart,i2c,spi三种协议简单引入)
    Http-Sumggling缓存漏洞分析
    Mybatis01、Mybatis简介
    【TA-霜狼_may-《百人计划》】图形4.2 SSAO算法 屏幕空间环境光遮蔽
    计算机毕业设计Java宠物互助领售平台(源码+系统+mysql数据库+lw文档)
    python带你制作随机点名系统,超级简单
    gdb调试程序教程
    Jaeger
    java后端笔记
    聊聊Mybatis的初始化之Mapper.xml映射文件的解析
  • 原文地址:https://blog.csdn.net/kangkanglhb88008/article/details/127828251