Qt中如何禁掉所有UI操作以及注意事项(处理各个widget的eventFilter这一层,但是感觉不好,为什么不使用QApplication呢)
刚做完的一个项目,在测试时出现了一个问题:由于多线程的存在,当进行语音识别时:如果用户点击程序界面上的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好。
http://blog.csdn.net/nrc_douningbo/article/details/5646247
Qt中如何禁掉所有UI操作以及注意事项(处理各个widget的eventFilter这一层,但是感觉不好,为什么不使用QApplication呢)的更多相关文章
- Qt中forward declaration of struct Ui::xxx的解决
		每当你新键一个 QT设计界面, QT会自动生成yyy.ui文件,如 <?xml version="1.0" encoding="UTF-8"?> & ... 
- Android之线程回掉更新ui
		一:工作线程中的回掉更新UI public class MainActivity extends AppCompatActivity { private int i; private Callback ... 
- QT中几个函数的使用方法
		一.把字符串转换成整形demo1:QString str = "FF";bool ok;int hex = str.toInt(&ok, 16); // hex == 25 ... 
- Qt中通过ui怎么引用不了pushbutton呢? 原来是这样…
		在Qt中打开一个项目在做, 突然想到要测量一下其中一个子系统,于是在当前环境下新建了一个项目并用qt designer 简单设计了一下ui,其中添加了pushbutton并命名为OpensourceB ... 
- 主线程中也不绝对安全的 UI 操作
		从最初开始学习 iOS 的时候,我们就被告知 UI 操作一定要放在主线程进行.这是因为 UIKit 的方法不是线程安全的,保证线程安全需要极大的开销.那么问题来了,在主线程中进行 UI 操作一定是安全 ... 
- qt中ui的 使用介绍
		1.什么是ui?ui通常是用Qt 设计师设计出来的界面文件的后缀.通常情况下ui是一个指向这个界面类的指针.ui-> 一般就是用来访问这个界面类里面的控件.例如你的ui文件里有一个叫okButt ... 
- 第32课 Qt中的文件操作
		1. Qt的中IO操作 (1)Qt中IO操作的处理方式 ①Qt通过统一的接口简化了文件和外部设备的操作方式 ②Qt中的文件被看作一种特殊的外部设备 ③Qt中的文件操作与外部设备的操作相同 (2)IO操 ... 
- 在多线程中进行UI操作
		那么在子线程中的UI操作如何处理呢?有两种方法: 一:在子线程,你需要进行的UI操作前添加dispatch_async函数,即可将代码块中的工作转回到主线程 dispatch_async(dispat ... 
- Android 子线程中进行UI操作遇到的小问题
		今天在学习<第一行Android代码>第9章-子线程进行UI操作时遇到了一些问题. 代码是这样的: ... import java.util.logging.Handler; ... pu ... 
随机推荐
- android 快速创建一个新的线程
			要给一个activity做成子线程的模式 第一种:直接创建子线程并启动 private Thread newThread; //声明一个子线程 new Thread() { @Override pub ... 
- python基础(四)
			内置函数 callable() #判断是否能够被调用执行,可以调用返回True,例如函数和类 chr() #将ascii值转换为字符,例如print(chr(65) )输出为a ord()#将字符转换 ... 
- Spring包的方法WebUtils.getParametersStartingWith(request,String)
			举个例子,比如页面上有 <input type="text" name="p_name" value="aileen"> < ... 
- python学习day2(一)
			一.上周作业回顾 1.登陆接口: 思路流程: 1.登陆,三次锁定用户 2.用户信息文件,黑名单文件 3.检测黑名单,如输入账号在黑名单中存在,不允许登陆 4.用户密码判断 主要知识点:while,fo ... 
- DataTables warning 错误警告
			今天使用 Charisma 框架的 jquery datatable 插件时出现如下错误: 搜索才发现 DataTables 目前不支持有单元格合并的表格.而且只要单元格数目不同就会有错误,不能使用搜 ... 
- EMV标准
			EMV标准是由国际三大银行卡组织--Europay(欧陆卡,已被万事达收购).MasterCard(万事达卡)和Visa(维萨)共同发起制定的银行卡从磁条卡向智能IC卡转移的技术标准,是基于IC卡的金 ... 
- linux学习之(三)-文件操作命令
			创建一个空文件: touch 文件名 例:touch tom 查看: 查看一个文件的内容命令cat 文件名 例:cat tom 注:cat命令并不能显示文件的所有信息,但屏幕显示的 行数是有 ... 
- javascript第十一课,string对象
			length: //字符串长度,索引从0开始 var str='说东方闪电方式的'; alert(str.length); charAt(index); var n='阿斯顿发生打算'; n.cha ... 
- Shortest Path(思维,dfs)
			Shortest Path Accepts: 40 Submissions: 610 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: ... 
- POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203
			后缀数组的买1送2题... HDU的那题数据实在是太水了,后来才发现在COJ和POJ上都是WA..原因在一点:在建立sa数组的时候里面的n应该是字符串长度+1....不懂可以去看罗大神的论文... 就 ... 
