Qt之事件系统_理论篇

文章目录

  • 简述:
  • QEvent类
  • 这段描述中提及的相关函数:
    • [static] bool QCoreApplication::sendEvent(QObject* receiver, QEvent* event)
    • [virtual] bool QCoreApplication::notify(QObject * receiver, QEvent * event)
    • [static] void QCoreApplication::postEvent(QObject* receiver, QEvent* event, int *priority* = Qt::NormalEventPriority)
    • [virtual] bool QObject::event(QEvent * e)
    • [virtual protected] bool QWidget::event(QEvent* event)
    • void QObject::installEventFilter(QObject* filterObj)
    • void QEvent::accept()
    • void QEvent::ignore()
    • [static] void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags *flags* = QEventLoop::AllEvents)
    • 重载函数:[static] void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags *flags*, int *maxtime*)

简述:

本文将对Qt中的事件部分进行分析。

QEvent类

Detailed Description
翻译:详细说明

The QEvent class is the base class of all event classes. Event objects contain event parameters.
翻译:QEvent类是所有事件类的基类。事件对象包含事件参数。

Qt's main event loop (QCoreApplication::exec()) fetches native window system events from the event queue, translates them into QEvents, and sends the translated events to QObjects.
翻译:Qt的主事件循环(QCoreApplication::exec())接收到本地窗体事件从事件队列中,把它们转化成QEvents,并且把转化的事件发送给QObjects。

In general, events come from the underlying window system (spontaneous() returns true), but it is also possible to manually send events using QCoreApplication::sendEvent() and QCoreApplication::postEvent() (spontaneous() returns false).
翻译:通常,事件来自底层窗体系统(spontaneous()返回true),但是也可以使用QCoreApplication::sendEvent() 和 QCoreApplication::postEvent() (spontaneous()返回false) 手动的发送事件。

QObjects receive events by having their QObject::event() function called. The function can be reimplemented in subclasses to customize event handling and add additional event types; QWidget::event() is a notable example. By default, events are dispatched to event handlers like QObject::timerEvent() and QWidget::mouseMoveEvent(). QObject::installEventFilter() allows an object to intercept events destined for another object.
翻译:QObjects接受事件通过调用它们的QObject::event()函数。这个函数可以在子类中重写去定制事件处理并且添加额外的事件类型;QWidget::event()是一个典型的例子。默认地,事件被派往事件处理者像QObject::timerEvent() 和 QWidget::mouseMoveEvent()。QObject::installEventFilter()允许一个对象去拦截发往其他对象的事件。

The basic QEvent contains only an event type parameter and an "accept" flag. The accept flag set with accept(), and cleared with ignore(). It is set by default, but don't rely on this as subclasses may choose to clear it in their constructor.
翻译:基本的QEvent仅仅包含一个事件类型参数和一个"accept"标志。这个“accept”标志用accept()设置, 用ignore()清除。它默认是设置的,但是不依赖于这个因为子类或许选择在它们的构造函数中清除它。

Subclasses of QEvent contain additional parameters that describe the particular event.
翻译:QEvent的子类包含额外的参数去描述特别的事件。

这段描述中提及的相关函数:

[static] bool QCoreApplication::sendEvent(QObject* receiver, QEvent* event)

bool QCoreApplication::sendEvent(QObject * receiver, QEvent * event)      【static】

Sends event event directly to receiver receiver, using the notify() function. Returns the value that was returned from the event handler.
翻译:直接发送事件event给接受者receiver,使用notify()函数。返回 事件处理者返回的值。

The event is not deleted when the event has been sent. The normal approach is to create the event on the stack, for example:
翻译:当事件已经被发送了后,事件没有被delete。常用的方法是在栈上,例如:
QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);
QApplication::sendEvent(mainWindow, &event);

[virtual] bool QCoreApplication::notify(QObject * receiver, QEvent * event)

Sends event to receiver: receiver->event(event). Returns the value that is returned from the receiver's event handler. Note that this function is called for all events sent to any object in any thread.
翻译:发送事件给接受者:receiver->event(event)。 返回 接收者事件处理者 返回的值。 注意:这个函数被调用 对于 在任何线程中发送到任何对象的任何事件。

For certain types of events (e.g. mouse and key events), the event will be propagated to the receiver's parent and so on up to the top-level object if the receiver is not interested in the event (i.e., it returns false).
翻译:对于某些类型事件(例如:鼠标和键盘事件),事件将被传播到接受者的父窗体,以此类推,直到最顶层的对象 如果 接受者对这个事件不关心(也就是说:它返回false)

There are five different ways that events can be processed; reimplementing this virtual function is just one of them. All five approaches are listed below:
翻译:有5种不同的方式去处理事件;重写这个虚函数仅仅是其中的一种方式。所有的5中方法列举如下:

1.Reimplementing paintEvent(), mousePressEvent() and so on. This is the commonest, easiest, and least powerful way.
翻译:重写paintEvent(), mousePressEvent()等等。这是最普遍的,最简单的,也是最不强大的方式。

2.Reimplementing this function. This is very powerful, providing complete control; but only one subclass can be active at a time.
翻译:重写这个函数。这是非常强大的,提供了完全的控制;但是每次只能有一个子类起作用。

3.Installing an event filter on QCoreApplication::instance(). Such an event filter is able to process all events for all widgets, so it's just as powerful as reimplementing notify(); furthermore, it's possible to have more than one application-global event filter. Global event filters even see mouse events for disabled widgets. Note that application event filters are only called for objects that live in the main thread.
翻译:安装一个事件过滤器在QCoreApplication::instance()上,这样的事件过滤器可以处理所有窗体的所有事件,因此它和重写notify()一样强大;而且,可以有多个 全局应用 的事件过滤器。全局的事件过滤器甚至可以捕获到使能的鼠标事件。注意:应用的事件过滤器只能被生存在主线程中的对象调用。

4.Reimplementing QObject::event() (as QWidget does). If you do this you get Tab key presses, and you get to see the events before any widget-specific event filters.
翻译:重写QObject::event() 【就像QWidget一样】。如果你这样做,你可以获取到Tab键按下,并且你可以在任何具体窗体的事件过滤器前获取到这个事件。

5.Installing an event filter on the object. Such an event filter gets all the events, including Tab and Shift+Tab key press events, as long as they do not change the focus widget.
翻译:在对象上安装事件过滤器。这样的事件过滤器可以获取到所有事件,包括Tab和Shift+Tab按键的事件,只要不改变窗体焦点。

Warning: If you override this function, you must ensure all threads that process events stop doing so before your application object begins destruction. This includes threads started by other libraries that you may be using, but does not apply to Qt's own threads.
翻译:注意:如果你重载这个函数,你必须确保在应用程序对象开始销毁之前,所有处理事件的线程都停止这样做。这包括你可能正在使用的其他库启动的线程,但不适用于Qt自己的线程。

[static] void QCoreApplication::postEvent(QObject* receiver, QEvent* event, int priority = Qt::NormalEventPriority)

Adds the event event, with the object receiver as the receiver of the event, to an event queue and returns immediately.
翻译:
添加事件event,对象receiver作为这个事件的接受者,到事件队列并且立即返回;
The event must be allocated on the heap since the post event queue will take ownership of the event and delete it once it has been posted. It is not safe to access the event after it has been posted.
翻译:
事件必须分配在堆上,因为 post事件队列将拥有这个事件的所有权 并且 delete它一旦它被posted。 这是不安全的去使用这个事件在它被posted以后。
When control returns to the main event loop, all events that are stored in the queue will be sent using the notify() function.
翻译:
当控制权返回到主事件循环,队列中的所有事件将被发送使用notify()函数。
Events are sorted in descending priority order, i.e. events with a high priority are queued before events with a lower priority. The priority can be any integer value, i.e. between INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more details. Events with equal priority will be processed in the order posted.
翻译:
事件按优先级减低的顺序排序,也就是说,拥有高优先级的事件在拥有低优先级的事件的前面。优先级可以是任意的整数,也就是说(包括)INT_MAX和INT_MIN之间的整数; 查阅Qt::EventPriority获取更多的信息。 相同优先级的事件将被处理按照被posted的顺序。

[virtual] bool QObject::event(QEvent * e)

This virtual function receives events to an object and should return true if the event e was recognized and processed.
翻译:这个虚函数接收去往一个对象的事件,如果事件e被识别和处理,它返回true。

The event() function can be reimplemented to customize the behavior of an object.
翻译:这个函数可以在子类中重写来自定义行为。

Make sure you call the parent event class implementation for all the events you did not handle.
翻译:确保你调用父类事件类的实现 对于你没有处理的所有事件。

Example:
class MyClass : public QWidget
  {
      Q_OBJECT

  public:
      MyClass(QWidget *parent = 0);
      ~MyClass();

      bool event(QEvent* ev)
      {
          if (ev->type() == QEvent::PolishRequest) {
              // overwrite handling of PolishRequest if any 【重写】
              doThings();
              return true;
          } else  if (ev->type() == QEvent::Show) {
              // complement handling of Show if any 【补充】
              doThings2();
              QWidget::event(ev);
              return true;
          }
          // Make sure the rest of events are handled
          return QWidget::event(ev);
      }
  };

[virtual protected] bool QWidget::event(QEvent* event)

Reimplemented from QObject::event().
翻译:
重写自QObject::event()函数。

This is the main event handler; it handles event event. You can reimplement this function in a subclass, but we recommend using one of the specialized event handlers instead.
翻译:
这是主要的事件处理者; 它处理事件event。 你可以在子类中重写这个函数, 但是我们建议使用专门的事件处理者的之一来代替。

Key press and release events are treated differently from other events. event() checks for Tab and Shift+Tab and tries to move the focus appropriately. If there is no widget to move the focus to (or the key press is not Tab or Shift+Tab), event() calls keyPressEvent().
翻译:
按键按下和释放事件 与其他事件处理是不同的。 event()检查Tab和Tab+Shift并且 尝试移动焦点适当的。 如果没有窗体去移动焦点(或者按键按下不是Tab或者Shift+Tab), event()调用 keyPressEvent().

Mouse and tablet event handling is also slightly special: only when the widget is enabled, event() will call the specialized handlers such as mousePressEvent(); otherwise it will discard the event.
翻译:
鼠标和平板电脑事件处理也有轻微的特殊; 仅仅当widget是使能的,event()将调用专门的处理者例如 mousePressEvent(); 否则它将会丢弃这个事件。 

This function returns true if the event was recognized, otherwise it returns false. If the recognized event was accepted (see QEvent::accepted), any further processing such as event propagation to the parent widget stops.
翻译:
这个函数返回true如果这个事件被识别, 否则返回false。 如果这个被设别的事件 被accepted(see QEvent::accepted), 任何更进一步的处理比如 事件传播到父窗体会停止。

void QObject::installEventFilter(QObject* filterObj)

Installs an event filter filterObj on this object. 
翻译:
安装一个事件过滤器filterObj在这个对象上。

For example:
  monitoredObj->installEventFilter(filterObj);
	
An event filter is an object that receives all events that are sent to this object. The filter can either stop the event or forward it to this object. The event filter filterObj receives events via its eventFilter() function. The eventFilter() function must return true if the event should be filtered, (i.e. stopped); otherwise it must return false.
翻译:
事件过滤器是一个对象,接收所有发送到这个对象的事件。 这个过滤器可以停止这个事件或者转寄给这个对象。 这个事件过滤器filterObj接收事件通过它的eventFilter()函数。 eventFilter() 函数必须返回true如果事件被过滤了,(也就是 停止了); 否则必须返回false。 

If multiple event filters are installed on a single object, the filter that was installed last is activated first.
翻译:如果多个事件过滤器被安装在同一个对象中, 最后一个被安装的过滤器首先活跃。 

Here's a KeyPressEater class that eats the key presses of its monitored objects:
翻译:这里有一个KeyPressEater类,吃了它被监控的对象的键盘presses事件:

class KeyPressEater : public QObject
  {
      Q_OBJECT
      ...

  protected:
      bool eventFilter(QObject *obj, QEvent *event);
  };

  bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
  {
      if (event->type() == QEvent::KeyPress) {
          QKeyEvent *keyEvent = static_cast(event);
          qDebug("Ate key press %d", keyEvent->key());
          return true;
      } else {
          // standard event processing
          return QObject::eventFilter(obj, event);
      }
  }

And here's how to install it on two widgets:
翻译:这里是如何把它安装在两个widgets中

KeyPressEater *keyPressEater = new KeyPressEater(this);
QPushButton *pushButton = new QPushButton(this);
QListView *listView = new QListView(this);

pushButton->installEventFilter(keyPressEater);
listView->installEventFilter(keyPressEater);

The QShortcut class, for example, uses this technique to intercept shortcut key presses.
翻译:这个QShortcut类, 例如,使用这个技术去拦截快捷键按下。

Warning: If you delete the receiver object in your eventFilter() function, be sure to return true. If you return false, Qt sends the event to the deleted object and the program will crash.
警告:如果你delete接收者对象在你的eventFilter()函数中,一定要返回true。 如果你返回false,Qt发送事件到被deleted的对象并且程序将奔溃。

Warning: If you delete the receiver object in your eventFilter() function, be sure to return true. If you return false, Qt sends the event to the deleted object and the program will crash.
Note that the filtering object must be in the same thread as this object. If filterObj is in a different thread, this function does nothing. If either filterObj or this object are moved to a different thread after calling this function, the event filter will not be called until both objects have the same thread affinity again (it is not removed).
注意事件过滤器对象必须与这个对象在同一线程中。 如果filterObj在一个不同的线程中,这个函数什么也不做。如果filterObj或者这个对象在调用这个函数后被moved到了一个不同的线程中,事件过滤器将不会被调用直到两个对象重新有相同的线程亲和度(它们是有关系的)。

void QEvent::accept()

Sets the accept flag of the event object, the equivalent of calling setAccepted(true).
翻译:设置这个事件对象的accept flag,与调用setAccepted(true)等同。
Setting the accept parameter indicates that the event receiver wants the event. Unwanted events might be propagated to the parent widget.
翻译:设置这个accept参数标志着 这个事件接收者 想要这个事件。 不想要的事件或许传播到父窗体。

void QEvent::ignore()

Clears the accept flag parameter of the event object, the equivalent of calling setAccepted(false).
翻译:清除这个事件对象的accept flag参数, 等同于调用setAccepted(false)函数。
Clearing the accept parameter indicates that the event receiver does not want the event. Unwanted events might be propagated to the parent widget.
翻译:清除这个accept参数标志着 事件接收者不想要 这个事件。 不想要 的事件或许被传播给父窗体。

[static] void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents)

Processes all pending events for the calling thread according to the specified flags until there are no more events to process.
翻译:处理所有将来的事件(在调用的线程中) 依据指定的flags, 直到没有更多的事件去处理。

You can call this function occasionally when your program is busy performing a long operation (e.g. copying a file).
翻译:你可以偶尔调用这个函数当你的程序正在忙于执行一个耗时的操作(例如:拷贝一个文件)

In the event that you are running a local loop which calls this function continuously, without an event loop, the DeferredDelete events will not be processed. This can affect the behaviour of widgets, e.g. QToolTip, that rely on DeferredDelete events to function properly. An alternative would be to call sendPostedEvents() from within that local loop.
你正在运行的一个本地事件循环,连续的调用这个函数,没有一个事件循环, 这个DeferredDelete事件将不会被处理。 这样可能会影响widgets的行为,例如,QToolTip依赖
DeferredDelete事件去正确的起作用。 一个替代方案是调用sendPostedEvents() 从本地循环的内部。

Calling this function processes events only for the calling thread.
翻译:调用这个函数处理事件 仅仅适用于调用的线程。

重载函数:[static] void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)

This function overloads processEvents().

Processes pending events for the calling thread for *maxtime* milliseconds or until there are no more events to process, whichever is shorter.
翻译:处理将来的事件(在调用的线程中), 最多maxtime 毫秒,或者直到没有更多的事件去处理, 无论哪一个是短期的。

You can call this function occasionally when your program is busy doing a long operation (e.g. copying a file).
翻译:你可以偶尔调用这个函数,当你的程序忙于执行一个耗时的操作(比如:拷贝一个文件)

Calling this function processes events only for the calling thread.
翻译:调用这个函数processes events仅仅对于调用的线程。


你可能感兴趣的:(Qt)