全部博文(584)
分类: WINDOWS
2011-04-20 09:06:04
创建用户事件
创建一个自定义类型的事件,首先需要有一个事件号,其值通常大于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();
- }
- }