Qt 이벤트 시스템

7908 단어

약술


Qt에서 이벤트는 대상이다. QEvent 추상 클래스에서 파생되어 응용 프로그램에서 발생하는 이벤트나 응용 프로그램이 처리해야 할 외부 활동에서 발생하는 이벤트를 나타낸다.
이벤트는 모든 QObject에서 파생된 하위 클래스 인스턴스 객체에 의해 수신 및 처리되지만 특정 컨트롤에 연관됩니다.다음은 이벤트가 전형적인 응용 프로그램에서 어떻게 발송되고 처리되는지 소개합니다.
  • 약술
  • 이벤트 발송 방법
  • 이벤트 유형
  • 이벤트 처리 프로그램
  • 이벤트 필터
  • 발송 이벤트
  • 이벤트 전송 방법


    일반적으로 이벤트가 발생할 때 Qt는 적절한 QEvent 하위 클래스 대상을 구성하여 이벤트의 발생을 표시하고 이벤트 () 함수를 호출하여 특정한 QObject (또는 하위 클래스) 대상에게 보냅니다.
    이 함수는 이벤트 자체를 처리하지 않고 먼저 받아들인 이벤트 유형을 검사한 다음에 이벤트 유형에 따라 해당하는 이벤트 처리 프로그램을 호출한다. 이벤트 처리 프로그램은 이벤트를 처리한 후에 bool 값을 되돌려 이 이벤트가 받아들여지고 무시되었다는 것을 나타낸다.
    일부 이벤트, 예를 들어 Qmouse Event와 QKey Event는 창 시스템에서 온 것이다.예를 들어 QTimerEvent 는 다른 이벤트 소스에서 온 것입니다.일부는 응용 프로그램 자체에서 나온다.

    이벤트 유형


    Qt는 다수의 이벤트 유형에 상응하는 종류를 세웠다. 흔히 볼 수 있는 것은 QResize Event, QPaint Event, Qmouse Event, QKey Event, QClose Event이다.
    각 특정 이벤트 클래스는 QEvent에서 상속되며 특정 이벤트 함수를 추가합니다.예를 들어 QResize Event는 크기 () 와oldSize () 를 추가하여 컨트롤러가 크기가 어떻게 바뀌었는지 알 수 있도록 합니다.
    일부 종류의 실제 지원은 하나의 이벤트 형식에 그치지 않는다.QmouseEvent는 마우스 버튼을 누르면 이벤트, 더블 클릭 이벤트, 이동 이벤트, 기타 관련 작업으로 인한 이벤트를 지원합니다.
    모든 이벤트는 연결된 유형이 있습니다. QEvent::Type에 의해 정의되어 있으며, 실행할 때 모든 이벤트 대상의 이벤트 유형을 쉽게 감지하여 이벤트 대상이 어떤 이벤트 클래스로 구성되었는지 신속하게 판단할 수 있습니다.
    프로그램은 다양하고 복잡한 이벤트와 상호작용을 해야 하기 때문에Qt의 이벤트 발송 메커니즘은 매우 유연하게 설계되었다.
    QCoreApplication::notify()의 문서는 전체 메커니즘을 간결하게 설명합니다.
    bool QCoreApplication::notify(QObject * receiver, QEvent * event) [virtual]

    이벤트를 수신자에게 보내기:receiver->이벤트(event).수신자의 이벤트 처리 프로그램에서 되돌아오는 값을 되돌려줍니다.이 함수는 프로그램의 모든 라인에 적용되는 대상에 적용됩니다.특정 유형의 이벤트 (예를 들어 마우스와 키보드 이벤트) 에서 이 이벤트는 수신자의parent에 전송되어 단계별로 업로드됩니다.
    최고급 대상에게 전송될 때까지 이 수신자들이 이 사건을 처리하지 않았다면 (예:false 되돌아오기).
    QCoreApplication::notify () 는 그 중 하나일 뿐입니다.다음과 같은 다섯 가지 방법이 있습니다.
  • paintEvent(), mousePressEvent() 등을 다시 쓴다.이것은 가장 자주 사용되고, 가장 간단하지만, 또한 가장 제한된 방식이다.
  • QCoreApplication::notify ()를 다시 씁니다.이것은 매우 강력해서 이벤트 처리를 완전히 제어할 수 있지만, 한 번에 하나의 하위 클래스에만 사용할 수 있다.
  • QCoreApplication::instance()에 이벤트 필터를 설치합니다.이 이벤트 필터는 모든 컨트롤의 모든 이벤트를 처리할 수 있기 때문에 notify () 를 다시 쓰는 것과 같이 강력합니다.또한 한 프로그램이 아닌 전체 이벤트 필터가 있고, 프로그램 전체 이벤트 필터는 컨트롤러가 비활성화된 마우스 이벤트를 받을 수 있습니다.주의: 프로그램 레벨 이벤트 필터는 주 라인에 존재하는 대상에만 사용할 수 있습니다.
  • QObject:::이벤트 () (QWidget처럼) 를 다시 씁니다.QObject::이벤트 () 를 다시 썼다면, 탭 키를 눌렀을 때, 컨트롤급 이벤트 필터에서 탭 키를 눌렀을 때 이 이벤트를 포착하기 전에 처리할 수 있습니다.
  • 해당하는 수신 대상에 이벤트 필터를 설치한다.예를 들어, 모든 이벤트를 포획하는 이벤트 필터참고: QObject:::이벤트 () 및 install EventFilter ().

  • 이벤트 프로세서


    이벤트를 처리하는 표준 방식은 허함수를 호출하는 것이다.예를 들어 QPaintEvent는 QWidget::paintEvent () 를 호출하여 처리합니다.이 허함수는 상응하는 처리를 책임지는데, 보통 이 컨트롤을 다시 그리는 것이다.만약 네가 실현한 허함수에서 필요한 모든 일을 하지 않았다면, 너는 그것의 기본 클래스를 호출해서 실현할 필요가 있다.
    예를 들어, 다음 코드는 사용자 정의 checkbox 컨트롤의 마우스 왼쪽 버튼 클릭 이벤트를 처리하고 다른 모든 클릭 이벤트를 기본 클래스인 QCheckBox에 전달합니다.
    void MyCheckBox::mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton) {
            //  
        } else {
            //  
            QCheckBox::mousePressEvent(event);
        }
    }

    만약 기본 클래스의 함수를 교체할 필요가 있다면, 모든 관련 처리를 스스로 실현해야 한다.단, 만약에 기본 클래스의 기능만 확장하고 싶다면, 실현해야 할 부분만 실현하고, 기본 클래스 처리 함수를 호출해서 처리하고 싶지 않은 상황을 처리하면 된다.
    때때로, 상응하는 처리 함수가 없는 특정한 이벤트를 처리하거나, 이벤트 처리 함수가 충분하지 않은 경우를 만나야 한다.가장 일반적인 예는 탭 누름 이벤트입니다.일반적으로 QWidget은 탭 키를 누르면 키보드 초점을 이동하지만, 소수의 컨트롤은 이 사건을 스스로 처리해야 한다.이 대상들은 QObject::이벤트 () 함수, 일반적인 이벤트 처리 프로그램을 다시 쓸 수 있으며, 일반적인 처리 과정 전이나 이후에 자신의 이벤트 처리 과정을 쓰거나 원래의 처리 과정을 완전히 대체할 수 있습니다.다음은 이와 같은 일반적인 컨트롤입니다.
    탭 이벤트를 직접 처리하고 특정 키 이벤트를 직접 처리한 다음 사용자가 처리하지 않아도 되는 다른 이벤트를 기본 클래스에 전달합니다.
    bool MyWidget::event(QEvent *event)
    {
        if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast(event);
        if (ke->key() == Qt::Key_Tab) {
            //  Tab 
            return true;
        }
        } else if (event->type() == MyCustomEventType) {
        MyCustomEvent *myEvent = static_cast(event);
        //  
        return true;
        }
    
        return QWidget::event(event);
    }

    주의: 처리되지 않은 이벤트에QWidget::이벤트 () 를 호출하고 이 기본 클래스에서 호출된 반환 값을 되돌려줍니다. 이벤트가 처리되었는지 여부를 표시합니다.true로 돌아가면 이 사건을 다른 대상에게 보내는 것을 금지합니다.

    이벤트 필터


    때때로 한 대상이 검사를 필요로 하고, 다른 대상으로 보내는 사건을 캡처할 수도 있다.예를 들어 대화상자는 보통 일부 컨트롤에 보내는 이벤트를 필터해야 합니다. 예를 들어 Enter 키가 눌린 이벤트 처리를 변경합니다.
    필터 대상의 QObject::install EventFilter () 함수를 호출하여 대상 대상에 이벤트 필터를 설정하면 필터 대상의 QObject::이벤트Filter () 함수에서 대상 대상에게 보내는 이벤트를 처리할 수 있습니다.이벤트 필터는 대상 대상이 이벤트를 받기 전에 이벤트를 처리합니다. 필터 대상이 필요할 때 이벤트를 검사하고 버릴 수 있습니다.QObject::removeEventFilter()를 호출하여 설치된 이벤트 필터를 제거할 수 있습니다.
    필터의 이벤트Filter () 가 호출되었을 때, 이 이벤트를 처리하든지, 이 이벤트를 전송하든지, 다른 대상에게 계속 처리하지 못하게 하든지 선택할 수 있습니다.모든 이벤트 필터가 이벤트를 계속 처리할 수 있도록 허용하면 (모든 필터가 처리된 후에false로 되돌아오기) 이 이벤트는 최종적으로 목표 대상에게 발송됩니다.만약 그 중 하나가 이 프로세스를 중지한다면 (true로 되돌아오기), 뒤에 있는 필터 대상과 목표 대상은 이 이벤트를 받지 않을 것입니다.
    bool FilterObject::eventFilter(QObject *object, QEvent *event)
    {
        if (object == target && event->type() == QEvent::KeyPress) {
            QKeyEvent *keyEvent = static_cast(event);
            if (keyEvent->key() == Qt::Key_Tab) {
                //  Tab 
                return true;
            } else
                return false;
        }
        return false;
    }

    위 코드는 특정 객체의 탭 키 이벤트를 캡처하여 보내는 또 다른 방법을 보여 줍니다.이 예에서, 이 필터는 탭 이벤트를 처리한 후true로 돌아가서 탭이 계속 처리되지 않도록 합니다.모든 다른 키 이벤트는 무시되고 필터는false로 돌아가서 이 이벤트가 설치된 후속 필터로 처리되어 최종적으로 목표 컨트롤러로 전송됩니다.
    또한 전체 응용 프로그램의 모든 이벤트를 필터할 수 있으며, 필터 대상을 QApplication이나 QCoreApplication 대상에 설치하기만 하면 된다.이러한 전역 이벤트 필터는 모든 대상 레벨 필터가 호출되기 전에 호출됩니다.
    이것은 매우 강력하지만 전체 응용 프로그램 범위 내의 모든 이벤트의 매번 처리 과정을 늦춘다.보통 다른 기술로 대체한다.

    이벤트 보내기


    많은 응용 프로그램들이 자신의 이벤트를 만들고 보내야 한다.당신은 Qt 자체의 이벤트 순환 메커니즘을 모방하여 적당한 이벤트 대상을 구축하고 QCore Application::send Event () 와 QCore Application::post Event () 를 호출하여 구성된 이벤트를 지정한 수신자에게 보낼 수 있습니다.
    sendEvent () 는 보낼 이벤트를 즉시 동기화합니다.되돌아올 때, 관련 이벤트 필터와/또는 목표 대상이 이 이벤트를 처리했음을 나타냅니다.대부분의 이벤트 클래스에 대해 isAccepted () 라는 함수는 이 이벤트가 처리되었는지 거부되었는지 판별할 수 있습니다.
    postEvent () 이벤트를 대기열에 전송합니다.다음 Qt의 주 이벤트가 순환적으로 실행될 때 대기열에 제출된 모든 이벤트를 스케줄링하여 최적화합니다.예를 들어, 만약 몇 개의 크기 변경 이벤트가 있다면, 그것들은 하나의 이벤트로 압축될 것이다.이것은 그림 이벤트에도 적용됩니다: QWidget::업데이트 () 는postEvent () 를 호출하여 여러 번 다시 그리는 것을 피하고 깜빡임과 속도를 향상시킵니다.
    postEvent () 는 제출한 이벤트가 해당 대상을 초기화한 후 아주 짧은 시간 안에 스케줄링되기 때문에 대상의 초기화 과정에도 사용됩니다.하나의 컨트롤을 실현할 때 사용자 정의 컨트롤의 구조 함수에서 이벤트 메커니즘을 가능한 한 빨리 지원하는 것은 매우 중요하다. 어떤 이벤트를 받아들일 수 있기 전에 구성원 변수를 가능한 한 빨리 초기화하는 것을 확보한다.
    사용자 정의 이벤트를 만들려면 이벤트 번호를 정의해야 합니다. 이 이벤트 번호는 QEvent:::User보다 크고, 사용자 정의 이벤트 형식에 대한 특정한 정보를 전달하기 위해 QEvent를 계승해야 할 수도 있습니다.

    좋은 웹페이지 즐겨찾기