创建用户事件

创建一个自定义类型的事件,首先需要有一个事件号,其值通常大于QEvent::User。
为了传递事件信息,因此必须编写自定义的事件类,该事件类从QEvent继承。

编写用户事件:
编写用户事件类的方法是首先定义一个事件号。
然后实现用户事件类,应用程序将把用户事件类于Qt的事件类同等处理。

//用户事件类QOriCodeEvent头文件qoricodeevent.h 
#include <QEvent>
#define ORI_DIS_EVENT QEvent::User+12

class 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())的更多相关文章

  1. Qt 自定义事件(三种方法:继承QEvent,然后Send Post就都可以了,也可以覆盖customEvent函数,也可覆盖event()函数)

    Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...

  2. Qt 自定义事件的实现

    初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢?看了篇文章,说先要子类化QEvent,然后定义自己的QEvent::Type,然后重写QWidget::event ...

  3. Qt 自定义事件

    Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...

  4. Qt自定义事件的实现(转)

    原文:http://blog.csdn.net/michealtx/article/details/6866094 初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢 ...

  5. Qt自定义事件的实现(军队真正干活,但要增加监军,大平台通知事件,事件内容自定义)

    初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢?看了篇文章,说先要子类化QEvent,然后定义自己的QEvent::Type,然后重写QWidget::event ...

  6. 组件自定义事件(.sync)实例

    <div id="root"> <parent></parent> </div> var childNode = { templat ...

  7. Qt 学习之路:自定义事件

    尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的.例如,我要支持一种新的设备,这个设备提供一种崭新的交互方式,那么,这种事件如何处理呢?所以,允许创建自己的事件 类型 ...

  8. Qt 学习之路 2(23):自定义事件

    Qt 学习之路 2(23):自定义事件  豆子  2012年10月23日  Qt 学习之路 2  21条评论 尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的.例如, ...

  9. 分享一个C#自定义事件的实际应用

    在C#.NET的开发中,事件是经常接触到的概念,比如为按钮添加点击事件,并写入点击按钮触发事件要运行的代码.不管是ASP.NET还是WinForm等各种形式的应用程序,最经常是为系统生成的事件写具体代 ...

随机推荐

  1. 关于cookie, iphone及chrome的异同

    http://www.blogjava.net/jjshcc/archive/2010/06/13/323517.html http://stackoverflow.com/questions/295 ...

  2. 模拟IIC总线汇编程序软件包

    一.概述 为了非常方便地对 I2C 从器件进行快速的.正确的读写操作,我们为此而设计出虚拟 I2C 总线操作平台软件包.本软件包是主方式下的虚拟 I2C 总线软件包,只要用户给子程序提供几个主要的参数 ...

  3. EBS查询用户客户化的文件配置

    select pro.profile_option_name, pro.user_profile_option_name, lev.level_type type, --lev.level_code, ...

  4. C# 文件夹操作

    追加文件    StreamWriter sw = File.AppendText(Server.MapPath(] != Path.DirectorySeparatorChar)         a ...

  5. chrome无法使用非官方商店扩展解决办法

        自己开发的工具性插件不想放在官方商店(当然也有可能是工作相关的工具不能放在官方商店),由于新版本的chrome不允许非官方商店的插件进行安装使用,所以出现一个头疼的问题:每次开启chrome都 ...

  6. JS帮你计算属相

        背景:一个人出生在2014年的正月初一,他的生肖到底是属蛇还是属马呢?这就要确定那一天才是一年的开始.是春节还是立春?每年的春节是正月初一,但是生肖必须是从立春日开始计算.春节是1912年孙中 ...

  7. Unity5 游戏小实例(方块男去打架吧)

    开发了将近半个月,最近进入一家游戏公司下班时间都是9点钟. 回到家里哪里还有时间去搞其他小东西, =.=这个小实例一直拖得太长了,先上一个版本.以后在慢慢修改.   项目下载地址: http://yu ...

  8. 【网络协议】TCP连接的建立和释放

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/29382883 TCP首部格式 先看TCP报文段的格式,例如以下; TCP报文段首部的前20 ...

  9. uva 1291(dp)

    题意:有一台跳舞机,中间是0.上左下右分别代表1 2 3 4,初始状态人站在中间.两仅仅脚都踏在0上,然后给出一段序列以0为结束,要按顺序踩出来,从0踏到四个方向须要消耗2点能量,从一个方向到相邻的方 ...

  10. [SQL学习笔记][用exists代替全称量词 ]

    学习sql的必经问题. 学生表student (id学号 Sname姓名 Sdept所在系) 课程表Course (crscode课程号 name课程名) 学生选课表transcript (studi ...