QsciScintilla编辑器从任意坐标拿到正确的行号

QSci官方API函数是:

    //! Returns the line which is at \a point pixel coordinates or -1 if there
    //! is no line at that point.
    int lineAt(const QPoint &point) const;
 

然而,当鼠标位置为空行的位置,此时拿到的行号总是-1,这个是不符号我们期望的。

查看其源码发现,里面用的是 SCI_POSITIONFROMPOINTCLOSE 这个宏,其实需要换另一个宏 SCI_POSITIONFROMPOINT 就可以了。说明这里的CLOSE表示是否封闭行,也就是是否有可见字符,或者用官方的话说是有效行

所以新的函数写法是:

//这个函数才能拿到空行的行号,而api函数QsciScintilla::lineAt在空行位置拿到的行号总是-1
int Editor::lineFromPos(QPoint pos)
{
    //根本原因在这里应该用SCI_POSITIONFROMPOINT,而不是SCI_POSITIONFROMPOINTCLOSE
    long chpos = SendScintilla(SCI_POSITIONFROMPOINT, pos.x(), pos.y());

    if (chpos < 0)
        return -1;

    return SendScintilla(SCI_LINEFROMPOSITION, chpos);
}

源码追踪:

想了解前因后果,看我这个博客:关于编辑器QScintilla(Scintilla)词法分析器工作原理的分析(实现注释区分)_我是标同学的博客-CSDN博客_qscintilla

如果我们追踪一下源码,可以发现Scitinall官方 Editor.cpp文件

	case SCI_POSITIONFROMPOINT:
		return PositionFromLocation(Point::FromInts(static_cast<int>(wParam) - vs.ExternalMarginWidth(), static_cast<int>(lParam)),
					    false, false);

	case SCI_POSITIONFROMPOINTCLOSE:
		return PositionFromLocation(Point::FromInts(static_cast<int>(wParam) - vs.ExternalMarginWidth(), static_cast<int>(lParam)),
					    true, false);


//核心就是这个函数,其实就是y坐标除以文本每行的高度,加上顶部行即可,也很简单的
Sci::Line Editor::LineFromLocation(Point pt) const {
	return pcs->DocFromDisplay(static_cast<int>(pt.y) / vs.lineHeight + topLine);
}

//核心就是这个函数,其实就是y坐标除以文本每行的高度,加上顶部行即可,也很简单的。

猜你喜欢

转载自blog.csdn.net/kangkanglhb88008/article/details/128326271