Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
shpory_GIIS.docx
Скачиваний:
3
Добавлен:
01.03.2025
Размер:
119.78 Кб
Скачать

11. Библиотека qt. Обработка событий.

Переопределение обработчиков событий.

В QT событие (event) — это экземпляр подкласса QEvent. QT обрабатывает более сотни типов событий, каждое из которых идентифицируется определенным значением перечисления.

Пример:QEvent::type() - определение, какой тип события произошел.

QEvent::MouseButtonPress.

По щелчку по изображению оно отображается в полноэкранном режиме.

Для событий некоторых типов недостаточно тех данных, которые могут хпаниться в простом объекте QEvent. Эта информация хранится в определенных одклассах QEvent.

События уведомляют объекты о себе при помощи функции event(), унаследованной от класса QObject. Реализация event QWidget передает больштнство событий конкретным обработчикам событий.

Рассмотрим обработку событий на примере событий клавиатуры:

События клавиатуры обрабатываются путем переопределения функции keyPressEvent(), keyReleaseEvent(). Если зажать кнопку — получаем много пресс без релиз.

Пример:

void CodeEditor::KeyPressEvent(QKeyEvent *event)
{    switch(event)
    {        case Qt::Key_Home:
        if(event->modifiers() & Qt::ControlModifier)
        {            goToBeginOfDocument();
        }
        else
        {            goToBeginLine()
        }
    }
    default:
        QWidget::keyPressEvent(event);
}

Важно — наличие default.

bool CodeEditor::event(QEvent *event)
{    if(event->tupe()==QEvent::KeyPress)
    {        QKeyEvent *keyEvent=static_cast<QKeyEvent*>event;
        if(keyEvent->key==Qt::Key_Tab)
        {            insertAtCurrentPosition('\t');            return true;
        }
    }    return QWidget::event(event);
}Если вместо true передать false событие передастся родителю.

12. Библиотека qt. Фильтры событий.

Фильтр событий позволяет одному объекту класса QObject перехватывать события другого объекта класса QObject еще до того, как они дойдут до последнего.

Рассмотрим пример передачи фокуса от одного поля ввода к другому.

Необходимо вначале сообщать виджету, что его события будут перехватываться.

MyClass::eventFilter(QObject *target,QEvent *event)
{
    if(target==firstNameEdit ||
    target==lastNameEdit ||
    target==cityEdit ||
    target==phoneEdit)
    {
        if(event->type()==QEventKeyPress)
        {
            QKeyEvent *keyEvent=static_cast<QKeyEvent*>event;
            if(keyEvent->key()==Qt::Key_Space)
            {
                focusNextChild();
                return true;
            }
        }
    }
    return QDialog::eventFilter(target,event);
}

События многих типов могут передаваться дальше по системе объектов приложения, если событие не было обработано ни на пути к целевому объекту, ни самим целевым объектом, то процесс обработки повторяется, но теперь в качестве целевого объекта используется родительский виджет. Этот процесс продолжается: управление передается от одного радительского объекта другому до тех пор, пока событие либо не будет обработано. Либо не достигнет верхнего уровня.

13. Библиотека qt. Обработка событий во время продолжительных процессов.

Цикл обработки событий начинается с вызова метода QApplication::exec();

При запуске приложения QT генерирует несколько событий для отображения виджетов на экране. После этого запускается цикл обраотки событий. В процессе обработки могут генерироваться другие события, которые ставятся в конец очереди событий. Если очень много времмени уходит на обрабоотку одного события, то интерфейс становится невосприимчив к действиям пользователя.Для обработки длительных действий можно использовать QApplication::processEvent(). Данная функция говорит QT о необходимости обработки ожидающих событий, находящихся в очереди и затем возвращает управление функции, вызвавшей ее.

void ImageView::SaveImage(Color image){    SaveImageHeader(imgHeader);
    for(int i=0;i<imgHeader.height;i++)
    {        for(int j=0;j<imgHeader.width;i++)        {            out<<image[imageHeader.width*i+j];        }        qApp->processEvent();    }}

При использовании этого метода существует опасность того, что пользователь может закрыть главное окно или повторно вызвать операцию сохранения. qApp->processEvent(QEventLoop::ExcludeUserInputEvents); - исключает события ввода пользователя.Часто при ввыполнении длительных процессов пользователю демонстрируется состояние при помощи виджета QProgressDialog.

    QProgressDialog process(this);    process.setLabelText(tr("Save Image"));
    process.setRange(0, imageHeader.height);    process.setModal(true);

Для проверки, что была нажата отмена испольщзуется метод:

if(process.wasCanceled())    {        out.remove();        return;    }

Существует так же другой способ работы с длительными процессами.

… Вместо того, чтобы начать выполнение операции по запросу пользователя данная операция откладывается до перехода приложения в состояние ожидания. Такая обработка применима к операциям, которые легко прервать и возобновить. В QT это реализуется при помощи ноль-милисекундного таймера. Таймер токого типа работает при отсутствии ожидающих событий.

void ImageView::timerEvent(QTimerEvent *event)
{    if(event->timerId()==myTimerID)
    {        while(step<maxStep && !qApp->hasPendingEvents())
        {            performerStep(step);            step++;
        }        
    }    else
    {        QDialog::timerEvent(event);    }}
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]