Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1681203
  • 博文数量: 584
  • 博客积分: 13857
  • 博客等级: 上将
  • 技术积分: 11883
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-16 09:34

分类: WINDOWS

2011-04-20 09:06:04

创建用户事件

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

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

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

  4.     class QOriCodeEvent : public QEvent
  5.     {
  6.     public:
  7.         QOriCodeEvent();
  8.     public:
  9.         int m_len;
  10.         char m_data[255];
  11.     };

  12.     //用户事件类QOriCodeEvent实现文件qoricodeevent.cpp
  13.     #include "qoricodeevent.h"

  14.     QOriCodeEvent::QOriCodeEvent()
  15.         : QEvent( Type(ORI_DIS_EVENT) )
  16.     {
  17.         //实现比较简单,随机获得指定长度的源码
  18.         m_len = rand()%150 + 50;
  19.         //0xeb 0x90 表示起始头,其他数据随机产生的。
  20.         m_data[0] = 235;
  21.         m_data[1] = 144;
  22.         for (int i = 2; i < m_len; i++)
  23.             m_data[i] = rand()%255;
  24.     }

事件发送
应用程序都要创建并发送自定义事件,因此先创建一个相应的事件类的对象,然后将事件发送。
QCoreApplication::sendEvent()、QCoreApplication::postEvent()都能完成事件发送操作。
senEvent()、postEvent()区别不用多说了吧~和Mfc中的SendMessage()、PostMessage()差不多。
只是postEvent()是投寄事件到一个队列,以便迟缓分发。

    发送用户事件:
这里为了简化实例,只在一个线程中定时发送,当然也可以在定时器事件中完成。
但由于用户事件不一定时时触发,最好还是定义个全局的QWaitCondition对象,通过wait()、wakeOne()来触发事件在线程中的发送。
QWaitCondition的相关内容留在以后写Qt线程中在讲解吧~

  1. //发送源码线程QOriThread头文件qorithread.h
  2.     #include <QThread>
  3.     class QOriThread : public QThread
  4.     {
  5.     public:
  6.         QOriThread();
  7.         virtual ~QOriThread();
  8.         void run();
  9.     private:
  10.         bool m_sign;
  11.     };

  12.     //发送源码线程QOriThread实现部分qorithread.cpp
  13.     #include "qoricodeevent.h"
  14.     #include "orithread.h"
  15.     #include <QApplication>
  16.     #include <mainwindow.h>
  17.     extern MainWindow *pMainwindow;

  18.     OriThread::OriThread()
  19.     {
  20.     }

  21.     OriThread::~OriThread()
  22.     {
  23.         m_sign = true;
  24.         wait();
  25.     }

  26.     void OriThread::run()
  27.     {
  28.         m_sign = false;
  29.      
  30.         while(true)
  31.         {
  32.             if(m_sign)
  33.                 break;
  34.             QOriCodeEvent *event = new QOriCodeEvent();
  35.             //pMainwindow是主窗口类的指针
  36.             qApp->postEvent( (QObject*)pMainwindow->textView, event);
  37.             sleep(1);
  38.         }
  39.     }

事件处理
有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()。

  1. //上面的textView就是QOriTextView类的对象。头文件qoritextview.h
  2.     #include "qoricodeevent.h"
  3.     #include <QTextEdit>

  4.     class QOriTextView : public QTextEdit
  5.     {
  6.     public:
  7.         QOriTextView(QWidget* parent = 0);
  8.         void ClearBuf();
  9.         QTextDocument *document;

  10.     protected:
  11.         void customEvent( QEvent *event );
  12.      
  13.     private:
  14.         QVector<QString> m_oriTextList;
  15.     };

  16.     //QOriTextView类实现部分qoritextview.cpp
  17.     #include "qoritextview.h"

  18.     QOriTextView::QOriTextView(QWidget* parent)
  19.         :QTextEdit(parent)
  20.     {
  21.         m_oriTextList.clear();
  22.         document = new QTextDocument(this);
  23.         //设置字体
  24.         QFont font = document->defaultFont();
  25.         font.setPointSize(11);
  26.         document->setDefaultFont(font);
  27.         document->setUseDesignMetrics(true);
  28.         //设置背景色黑色
  29.         setPalette(Qt::black);
  30.         setDocument(document);
  31.         //设置滚动条暗灰色
  32.         verticalScrollBar()->setPalette(Qt::darkGray);
  33.         //文本形式为只读
  34.         setReadOnly(true);
  35.         setUndoRedoEnabled(true);
  36.     }

  37.     void QOriTextView::ClearBuf()
  38.     {
  39.         clear();
  40.         m_oriTextList.clear();
  41.     }

  42.     void QOriTextView::customEvent( QEvent *event )
  43.     {
  44.         int type = event->type();
  45.         if ( type == ORI_DIS_EVENT )
  46.         {
  47.             //将QOriCodeEvent发来的数据写到oriText中。
  48.             QString oriText;
  49.             for(int i=0; i<((QOriCodeEvent*)event)->m_len; i++)
  50.             {
  51.                 QString tempStr;
  52.                 tempStr.sprintf("%02X ", (unsigned char)(((QOriCodeEvent*)event)->m_data[i]));
  53.                 oriText += tempStr;
  54.             }
  55.             //设置文本字体颜色白色
  56.             setTextColor(Qt::white);
  57.             append(oriText);
  58.             m_oriTextList.push_back(oriText);
  59.             //当数据大于15条后,清除顶方数据
  60.             if (m_oriTextList.count() > 15)
  61.             {
  62.                 QTextCursor cursor(document);
  63.                 if (cursor.isNull())
  64.                 {
  65.                     cursor.movePosition(QTextCursor::Start);
  66.                     cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
  67.                     cursor.deleteChar();
  68.                     m_oriTextList.pop_front();
  69.                 }
  70.             }
  71.             //滚动条始终在最下面
  72.             QScrollBar *vScrollBar = verticalScrollBar();
  73.             qreal high = vScrollBar->maximum() - vScrollBar->minimum() + vScrollBar->pageStep();
  74.             vScrollBar->setSliderPosition(vScrollBar->maximum());
  75.             event->accept();
  76.         }
  77.     }
阅读(1870) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~