Qt中如何禁掉所有UI操作以及注意事项(转)

摘要:
所谓“禁用所有UI操作”,主要是指手机和其他手持设备上的“禁用鼠标操作”,尤其是具有纯触摸屏的设备!禁用UI操作时:如果我们同时拦截绘制事件,则无法更新进度条!对所有丢失的窗口执行上述操作后,我们发现几乎所有的窗口UI操作都被成功禁用,除了QTextEdit,这导致程序再次崩溃!如果要允许QTextEdit的UI操作,请隐藏它!

 刚做完的一个项目,在测试时出现了一个问题:由于多线程的存在,当进行语音识别时:如果用户点击程序界面上的button或者其他接受点击事件后会发出信号的widget时,程序会crash ! 后来尝试着从多线程上去解决,但是比较困难;后来只能从另外一条路来解决,那就是:当语音识别进行时:禁掉一切用户操作!

      所谓的禁掉一切UI操作,在手机等手持设备上,尤其是纯触摸屏的设备上,主要就是指的禁止mouse操作!当然了:也可能是禁止键盘操作等。那如何去做这一点呢?

      方法:我们可以截获禁止操作的窗口的所有event事件,而后将他们全部抛掉而不进行处理,这样就可以了。那在Qt中要实现这一点有很多种方法,比较常用的方式就是使用eventFilter事件过滤器。 

      这其中不可避免要说到Qt中的事件传递顺序,其要经过很多层()对于我而言:我用的比较多的层次就是QApplication的eventFilter这一层 , 各个widget的eventFilter这一层 各个widget的event()这一层以及 各个widget里边的各个事件处理函数这一层(这四层的传递顺序是从前往后)

      这里我们只需要使用各个widget的eventFilter即可! 可以如下写:

     bool iEnableOperator = true;

     myWidget::eventFilter(QObject *obj, QEvent *event)

{

if (iEnableOperator  == true)

{

if(event->type() == QEvent::paint)

{

return false;

}

else

{

                             return true;
                    }
             }
             else
             {
                    return QWidget::eventFilter(obj, event);
             }
     }
   
     而后我们只需要改变iEnableOperator 这个变量的值 即可决定允许不允许进行UI操作!
//-------------------------------------------------------------------------------------------------------------------------------------------
  这里有以下几点注意:
     1:当禁止UI操作时:并不是要把所有event都要拦截掉,而是要把paint绘制事件给漏过去(正如上边所做的那样),因为我们仅仅是要禁止
UI操作,而不是不再更新绘制!  比如:在做语音识别的时候,我们再界面上显示一个进度条,其上边的值是逐渐增大的。 当禁止UI操作时:如果
我们同时拦截了paint绘制事件,那进度条也无法更新显示了!  基于以上理由,我们需要把paint事件给漏过去!
    2:这里有一个特殊的空间:QTextEdit 。当我们后来对所有的窗口不见都做如上操作后发现:几乎所有窗口的UI操作都顺利禁掉了,唯独QTextEdit
的没有,导致程序还会发生crash!  后来追了一下这个问题发现:无论是在windows下还是symbian下,QTextEdit的事件传递过程都很另类!对于
所有的mouse事件,其在传递过程中不经过任何一个其注册的eventFilter事件过滤器,也不经过自身重写的event(),而是直接进入到了自己的
事件处理函数中(mousePressEvent()等等。。)!   
      对于这一点:我一直觉得没什么道理可言,因为别的空间,比如QPushButton都是经过的,唯独它不经过!Maybe这是QTextEdit的另外一个bug!!
      后来我们用如下方法禁掉了QTextEdit的mouse事件: 
       ①:首先准备一个标准的QWidget对象,将其透明度设为0.1,大小与QTextEdit相同,位置设置为QTextEdit对象的位置,亦即:让二者是一种前后
             重叠的关系。初始时将这个窗口hide掉!
       ②: 当需要禁止QTextEdit的UI操作时(以我们的项目为例:就是当开始语音识别时),将前边创建的半透明窗口raise并show在QTextEdit
            的前边来遮挡住QTextEdit本身。而当要允许QTextEdit的UI操作时则再将其hide掉!
      其实道理也很简单:将QTextEdit挡住了,那事件就传递不到它上边,从而也就禁止掉了。由于我们将这个窗口透明度设置为0.1,几近全透明,
用户根本体验不到是我们在上边覆盖了一个窗口。
//-------------------------------------------------------------------------------------------------------------------------------------------
  再补充一个关于QTextEdit的bug:   QTextEdit这个控件在windows和symbian下的表现是很不一样的!
      在windows下其表现很正常,但是在symbian下:其scrollBar上边的slider滑块长度大小永远不发生变化,按理说:其文字所占的屏数越多,
滑块的长度越短才对。 这一点就让用户无法通过滑动这个slider来达到翻屏的效果。
     但是symbian下的QTextEdit却给出了几个菜单:当常按两个方向箭头时:其会跳出一个menu来,上边有几个选项:主要就是让滚动到
开头处,滚动到结尾处等。 它通过这种方式弥补了滑动块长度大小不变的问题。但是我觉得这个的用户体验度始终没有用slider好。

免责声明:文章转载自《Qt中如何禁掉所有UI操作以及注意事项(转)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇几种基于token 认证的标准【转载】sp_spaceused2,看库里全部表占用的物理空间下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

cocos creator基础-cc.Node(二)事件响应

触摸事件 1: 触摸事件类型: START, MOVED, ENDED(物体内), CANCEL(物体外);2: 监听触摸事件: node.on(类型, callback, target(回掉函数的this), [useCapture]);3: 关闭触摸事件: node.off(类型, callback, target(回掉函数的this), [useCa...

浏览器窗口关闭事件的监听搜集

转自:http://www.2cto.com/kf/201108/100769.html 方式一:(适用与IE浏览器,而且刷新不提示,只在点击浏览器关闭按钮的时候提示)<script type="text/javascript">window.onbeforeunload=onclose;function onclose(){if(event....

Flash AS3 解决SWF加载报错问题

一个SWF加载另一个SWF时,先看下我们用的加载代码: AS3代码 varloadSwf:Loader =newLoader; loadSwf.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCom) loadSwf.load(newURLRequest("demo.swf")) p...

websocket前后端交互

一.目录 websocket的简介 websocket客户端 websocket服务端 测试运行WebSocketWebSocket是HTML开始提供的一种浏览器与服务器间进行全双工通讯网络技术,依靠这种技术和服务器端的长连接,双向实时通讯.特点:事件驱动,异步,使用ws或者wss协议的客户端socket,能够实现真正意义上的推送功能缺点:少部分浏览器不...

div拖拽, onmousedown ,onmousemove, onmouseup

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style type="text/css"> 7...

Python学习之路:红绿灯例子

importtime,threading event =threading.Event() deflighter(): count =0 event.set() whileTrue: if count > 5 and count < 10:#改成红灯 event.clear()...