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 ...
随机推荐
- 开发移动端web应用, 使用手机自带键盘的搜索按钮
很多时候在移动端的web页面中, 需要使用搜索功能, 然而页面中并没有太多的空间来放置一个像pc端上那样的搜索按钮, 这时候就需要借用手机输入法自带的搜索按钮来实现点击搜索 虽然不是什么大的功能, 但 ...
- hdu 5442 Favorite Donut 最大表示法+kmp
题目链接 给你一个字符串, 然后把他想象成一个环. 从某一个地方断开,然后逆时针或顺时针, 都可以形成一个字符串, 求字典序最大的那种. 输出断开位置以及是顺时针还是逆时针. 如果两个一样, 输出位置 ...
- 《UNIX网络编程》TCP客户端服务器例子
最近在看<UNIX网络编程>(简称unp)和<Linux程序设计>,对于unp中第一个获取服务器时间的例子,实践起来总是有点头痛的,因为作者将声明全部包含在了unp.h里,导致 ...
- 重新关联bat文件的打开方式为系统默认方式
为什么“BAT”扩展名的默认打开方式:显示出来的居然是“%1”这么一个怪异的东东,具体在什么位置的? c:\windowssystem32\command.com修复bat关联,打开command.c ...
- mvn 一些操作
拷贝依赖包 mvn dependency:copy-dependencies -DoutputDirectory=src/main/webapp/WEB-INF/lib -DincludeScope ...
- flex lineChart中自定义datatip
原文 http://www.giser.net/?p=776 在Flex4中使用lineChart会遇到一个bug,datatip上的背景是黑色的,造成文字看不清楚,和整体界面不协调. 那么解决这个问 ...
- 50% 的财富 500 强企业使用 Windows Azure
在上周的北美TechEd大会上,我有幸见到了来自世界各地的客户.合作伙伴和分析师,其数量之多,让人震惊.没有什么比亲耳聆听使用 Windows Azure 来开创新天地的客户亲口讲述他们的故事更令人振 ...
- 练习3.20 a 将中缀表达式转换为后缀表达式
//将中缀表达式转换为后缀表达式 int main() { ; ]={,,,,,,,}; char tmp; PtrToStack s; s = CreateStack( MaxSize ); ) { ...
- poj1503---大数加法
先讲一种错误的做法:WA了n次,大神一定帮我看一下//看到有说数组大小开到250,我改了之后还是不//思路是将arr这个数组的每一行附上输入的值,然后求每列所有数之和,当然进位 //maxlen记录这 ...
- Aix6.1安装openssh
一.软件下载 1.官方网站下载: openssl IBM官方网站下载:https://www14.software.ibm.com/webapp/iwm/web/reg/download.do?sou ...