Qt 自定义事件详细实例(继承QEvent,然后QCoreApplication::postEvent()、sendEvent())
创建用户事件
创建一个自定义类型的事件,首先需要有一个事件号,其值通常大于QEvent::User。
为了传递事件信息,因此必须编写自定义的事件类,该事件类从QEvent继承。
编写用户事件:
编写用户事件类的方法是首先定义一个事件号。
然后实现用户事件类,应用程序将把用户事件类于Qt的事件类同等处理。
//用户事件类QOriCodeEvent头文件qoricodeevent.h
#include <QEvent>
#define ORI_DIS_EVENT QEvent::User+12class QOriCodeEvent : public QEvent
{
public:
QOriCodeEvent();
public:
int m_len;
char m_data[255];
};//用户事件类QOriCodeEvent实现文件qoricodeevent.cpp
#include "qoricodeevent.h"QOriCodeEvent::QOriCodeEvent()
: QEvent( Type(ORI_DIS_EVENT) )
{
//实现比较简单,随机获得指定长度的源码
m_len = rand()%150 + 50;
//0xeb 0x90 表示起始头,其他数据随机产生的。
m_data[0] = 235;
m_data[1] = 144;
for (int i = 2; i < m_len; i++)
m_data[i] = rand()%255;
}
事件发送
应用程序都要创建并发送自定义事件,因此先创建一个相应的事件类的对象,然后将事件发送。
QCoreApplication::sendEvent()、QCoreApplication::postEvent()都能完成事件发送操作。
senEvent()、postEvent()区别不用多说了吧~和Mfc中的SendMessage()、PostMessage()差不多。
只是postEvent()是投寄事件到一个队列,以便迟缓分发。
发送用户事件:
这里为了简化实例,只在一个线程中定时发送,当然也可以在定时器事件中完成。
但由于用户事件不一定时时触发,最好还是定义个全局的QWaitCondition对象,通过wait()、wakeOne()来触发事件在线程中的发送。
QWaitCondition的相关内容留在以后写Qt线程中在讲解吧~
//发送源码线程QOriThread头文件qorithread.h
#include <QThread>
class QOriThread : public QThread
{
public:
QOriThread();
virtual ~QOriThread();
void run();
private:
bool m_sign;
};//发送源码线程QOriThread实现部分qorithread.cpp
#include "qoricodeevent.h"
#include "orithread.h"
#include <QApplication>
#include <mainwindow.h>
extern MainWindow *pMainwindow;OriThread::OriThread()
{
}OriThread::~OriThread()
{
m_sign = true;
wait();
}void OriThread::run()
{
m_sign = false;
while(true)
{
if(m_sign)
break;
QOriCodeEvent *event = new QOriCodeEvent();
//pMainwindow是主窗口类的指针
qApp->postEvent( (QObject*)pMainwindow->textView, event);
sleep(1);
}
}
事件处理
有5种不同的处理事件的方法,如下
1、重载函数QCoreApplication::notify()可提供有效的事件控制,但仅能在派生于QCoreApplication、QApplication的类中重实现这个函数。
2、在qApp(是QApplication的全局实例)中实现事件过滤,这样的一个事件过滤器能为所有的widget处理所有的事件,而且可以有超过一个全局应用程序的事件过滤器。如鼠标事件的全局事件过滤器设置了鼠标跟踪事件,则鼠标移动事件对于所有widget有效。
3、重载QObject::event()(在QWidget类中)在任何widget特定的事件过滤器之前可看到所有事件。
这个虚函数接收一个对象的事件,如果事件被识别并被处理,将返回true。这个函数能被用来重实现一个对象的行为。
4、在对象上安装事件过滤器。
5、重载Qt基类事件处理函数。
当用户发现Qt基类的事件处理函数不能满足需要时,可以在用户类中重载这些函数。对于特定的Qt事件,可以重载特定的事件函数,如重载paintEvent()、mousePressEvent()等函数。
处理用户事件:
如果想处理多个Qt事件处理函数,可以通过重载QObject::event()来实现。
但这个我们是要处理的是自定义用户事件,这个要重载的是QObject::customEvent()。
//上面的textView就是QOriTextView类的对象。头文件qoritextview.h
#include "qoricodeevent.h"
#include <QTextEdit>class QOriTextView : public QTextEdit
{
public:
QOriTextView(QWidget* parent = 0);
void ClearBuf();
QTextDocument *document;protected:
void customEvent( QEvent *event );
private:
QVector<QString> m_oriTextList;
};//QOriTextView类实现部分qoritextview.cpp
#include "qoritextview.h"QOriTextView::QOriTextView(QWidget* parent)
:QTextEdit(parent)
{
m_oriTextList.clear();
document = new QTextDocument(this);
//设置字体
QFont font = document->defaultFont();
font.setPointSize(11);
document->setDefaultFont(font);
document->setUseDesignMetrics(true);
//设置背景色黑色
setPalette(Qt::black);
setDocument(document);
//设置滚动条暗灰色
verticalScrollBar()->setPalette(Qt::darkGray);
//文本形式为只读
setReadOnly(true);
setUndoRedoEnabled(true);
}void QOriTextView::ClearBuf()
{
clear();
m_oriTextList.clear();
}void QOriTextView::customEvent( QEvent *event )
{
int type = event->type();
if ( type == ORI_DIS_EVENT )
{
//将QOriCodeEvent发来的数据写到oriText中。
QString oriText;
for(int i=0; i<((QOriCodeEvent*)event)->m_len; i++)
{
QString tempStr;
tempStr.sprintf("%02X ", (unsigned char)(((QOriCodeEvent*)event)->m_data[i]));
oriText += tempStr;
}
//设置文本字体颜色白色
setTextColor(Qt::white);
append(oriText);
m_oriTextList.push_back(oriText);
//当数据大于15条后,清除顶方数据
if (m_oriTextList.count() > 15)
{
QTextCursor cursor(document);
if (cursor.isNull())
{
cursor.movePosition(QTextCursor::Start);
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
cursor.deleteChar();
m_oriTextList.pop_front();
}
}
//滚动条始终在最下面
QScrollBar *vScrollBar = verticalScrollBar();
qreal high = vScrollBar->maximum() - vScrollBar->minimum() + vScrollBar->pageStep();
vScrollBar->setSliderPosition(vScrollBar->maximum());
event->accept();
}
}
转自:http://cool.worm.blog.163.com/blog/static/6433900620084632410879/
http://blog.csdn.net/leo115/article/details/7403033
Qt 自定义事件详细实例(继承QEvent,然后QCoreApplication::postEvent()、sendEvent())的更多相关文章
- Qt 自定义事件(三种方法:继承QEvent,然后Send Post就都可以了,也可以覆盖customEvent函数,也可覆盖event()函数)
Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...
- Qt 自定义事件的实现
初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢?看了篇文章,说先要子类化QEvent,然后定义自己的QEvent::Type,然后重写QWidget::event ...
- Qt 自定义事件
Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...
- Qt自定义事件的实现(转)
原文:http://blog.csdn.net/michealtx/article/details/6866094 初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢 ...
- Qt自定义事件的实现(军队真正干活,但要增加监军,大平台通知事件,事件内容自定义)
初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢?看了篇文章,说先要子类化QEvent,然后定义自己的QEvent::Type,然后重写QWidget::event ...
- 组件自定义事件(.sync)实例
<div id="root"> <parent></parent> </div> var childNode = { templat ...
- Qt 学习之路:自定义事件
尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的.例如,我要支持一种新的设备,这个设备提供一种崭新的交互方式,那么,这种事件如何处理呢?所以,允许创建自己的事件 类型 ...
- Qt 学习之路 2(23):自定义事件
Qt 学习之路 2(23):自定义事件 豆子 2012年10月23日 Qt 学习之路 2 21条评论 尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的.例如, ...
- 分享一个C#自定义事件的实际应用
在C#.NET的开发中,事件是经常接触到的概念,比如为按钮添加点击事件,并写入点击按钮触发事件要运行的代码.不管是ASP.NET还是WinForm等各种形式的应用程序,最经常是为系统生成的事件写具体代 ...
随机推荐
- Keil C51内存分配与优化
C51的内存分配不同于一般的PC,内存空间有限,采用覆盖和共享技术.在Keil编译器中,经过编译后,会形成一个M51文件,在其内部可以详细的看到内存的分配情况. C51内存常见的两个误区: A.变量超 ...
- python 文件中的中文编码解决方法
# -*- coding: utf-8 -*- #查看安装的SDK默认的编码字符集在脚本中可以修改你的编码格式, 方法如下:#sys.getdefaultencoding()#reload(sys)# ...
- 使用 C# 编写简易 ASP.NET Web 服务器
原文 http://www.cnblogs.com/lcomplete/p/use-csharp-write-aspnet-web-server.html 如果你想获得更好的阅读体验,可以前往我在 g ...
- 关于导入oracle10g的数据到sqlserver2005里的方案总结
由于项目需求,现需要将oracle的数据全部导入到sqlserver中,一下算是自己的总结小计吧. sqlserver有自己的导入数据的功能,其中就有提供两种方式从oracle导入数据. 两种方式就不 ...
- ssh添加公钥
ssh-keygen生成公钥存储在文件: ~/.ssh/id_rsa.pub 如果ssh-add -l命令后没有一串长的字符串, 把私钥密钥对的ID(fingerPrint)加入ssh的认证代理ssh ...
- Tomcat启动load action异常
近期将之前的项目移到另一个文件夹中(包的路径也更改了),启动Tomcat之后包错:无法加载action,看错误提示知道是路径错误,网上也有各种各样的解决方案,这里我的错误是因为项目移到了别的文件中,所 ...
- Poj2946-The Warehouse(bfs+哈希)
题目我就不粘贴了... 题意:给出地图,最大8*8,出口用'E'表示,空地用'.'表示,数字表示此处有多少个箱子,主人公的起点应该是在有箱子的地方,他可以朝四个方向移动,但是只有两种方式 一种是他移动 ...
- 让 SpringMVC 接收多个对象的4种方法
问题背景: 我要在一个表单里同时一次性提交多名乘客的个人信息到SpringMVC,前端HTML和SpringMVC Controller里该如何处理? 第1种方法:表单提交,以字段数组接收: 第2种方 ...
- Java应用开发的一条经验
一旦为应用建立良好的基础设施, 后续的开发就会变得容易而快速. 这些基础设施包括: 1. 线程池的建立.配置: 在 JDK 并发库的基础上建立更适合于应用的并发使用接口: 2. 跨多数据源的 ...
- SQL 查找 45道练习题
一. 设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表(一)~表( ...