qt单线程实现顺序事件的处理不卡顿技巧(IDE开发)

需求:

我现在是这样的需求,我正在开发一款嵌入式IDE中,编辑器中光标改变,右侧的符号大纲能对应的改变选中项。

这里的过程是这样的,鼠标位置改变事件函数里,通过光标行号,计算得到当前处于的符号(这是个耗时过程),然后在右侧的大纲里选中对应符号。

问题:

用户可能会快速的改变光标位置,导致一连串的鼠标位置改变事件需要处理,从而光标位置改变就是卡顿的。

这个问题的处理方法:

1. 就串行处理,事件函数里判断光标所在行是不是和上次仍然相同,如果所在行相同,那么就不更新大纲位置了。这样来加快不必要的更新。

2. 用一个定时器,当光标位置停下来了100ms后,再处理这个符号位置更新。这样能让连续事件得到丢弃处理。但是光标停下来了,此时如果定时到了,正在处理大纲,光标刚好又动了,此时光标就被卡住了。这个情况发生的可能性还是很小的。

3. 多线程方式,每次更新前就启动一个线程,而且先判断前一个线程是否还未完成,如果还未完成,先停止前一个线程。这个用QtConcurrent::run就行,比较轻量化的线程使用。改成多线程后,源文件为15000行(stm32f407xx.h),也不卡了。 QtConcurrent::run(mWidgetSymbolBrowser, &WidgetSymbolBrowser::fillSymbols, editor->filename(), false);。这个有返回值的,可以查询到这个线程的状态,从而新另一个新线程启动的时候,可以去操控这个正在运行的线程了。

4. 在处理过程中调用qt的事件处理循环(这样会产生事件重入),同时结合两个标志变量,就能解决问题重入了,此时只有最后一次的重入才会更新界面。中途处理系统事件了,界面也不会卡顿了。本方法见本文末尾。
 

总结:

方法1逻辑最清晰,在性能无明显影响的情况下,当然就用这个啦。方法2也不错,实现复杂一点,但是比方法1性能好。方法3有点重量化了,需要开线程。方法4逻辑复杂,但是比方法1和2的性能都强。

这里我的符号表不大,所以方法1是可以满足性能了的,所以就用这个。

方法4伪代码与示意图:

int level = 0;

bool can'tUpdate = false;

void cursorChangeEvent(int line)

{

        level++;

        耗时计算(line);

        QApplication::processEvent();

        if(can'tUpdate == false)

                更新符号大纲();

        level--;

        if(level > 0)

                can'tUpdate = true;

}

猜你喜欢

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