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(); } }
义事件详细实例。