Qt 自定义事件详细实例



Qt 自定

创建用户事件

创建一个自定义类型的事件,首先需要有一个事件号,其值通常大于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 0×90 表示起始头,其他数据随机产生的。     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();     } }

义事件详细实例。