Russian Qt Forum
Ноябрь 24, 2024, 06:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Загрузка процессора 50% при обработке события QEvent::Paint  (Прочитано 3941 раз)
radislav72
Гость
« : Апрель 27, 2010, 07:32 »

Старался сделать форму ввода с подсвечиваемыми полями:
http://www.prog.org.ru/topic_13273_0.html

Все работает хорошо, но при постоянном перерисовывании окна загрузка процессора возрастает до 50%. Как-то не хорошо получается. Форма ввода достаточно большая- до 30 полей.

Как правильней сделать, чтобы и поля выделялись, и процессор зря не нагружался?

Код такой:
Код:
bool mem_new_phpDialog::eventFilter(QObject *o, QEvent *e)
{
    QDate limDate;
    limDate.setDate(1900, 1, 1);

    if(e->type() == QEvent::Paint)
    {
        if(o->property("requiredField").toBool())
        {
            QWidget * w = dynamic_cast<QWidget *>(o);
            if(w && w->parentWidget()) {
                w->parentWidget()->update(QRect(w->pos(), w->size()).adjusted(-2, -2, 2, 2));
            }
        } else {
            QPainter p(qobject_cast<QWidget *>(o));
            QPen pen_;
            pen_.setWidth(1);
            pen_.setColor(QColor(255, 183, 183)); // Set border color
            p.setPen(pen_);
            p.setRenderHint(QPainter::Antialiasing);

            bool ready_ = true;

            foreach(QObject * obj, o->children())
            {
                if(obj->property("requiredField").toBool()) // Check widget
                {

                    if(
                            (obj->inherits("QLineEdit") && obj->property("text").toString().isEmpty()) ||
                            (obj->inherits("QComboBox") && obj->property("currentText").toString().isEmpty()) ||
                            (obj->inherits("QComboBox") && obj->property("currentText").toString().toLower() == tr("- не вказано -")) ||
                            (obj->inherits("QDateEdit") && obj->property("date").toDate() <= limDate) ||
                            (obj->inherits("QGroupBox") && obj->property("objectName").toString() == "gbSex" && ui->rbUnknown->isChecked())
                            )
                    {
                        ready_ &= false;
                        QWidget * w = dynamic_cast<QWidget *>(obj);
                        if(w)
                        {
                            QRect r(w->pos(), w->size());
                            p.drawRect(r.adjusted(-1, -1, 1, 1));
                        }
                    }
                }
            }
        }
    }
    return QDialog::eventFilter(o, e);
}

С Qt только начинаю, так что извиняюсь, если вопрос примитивный...Улыбающийся
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Апрель 27, 2010, 10:13 »

Это фильтр будет отрабатывать для _всех_ событий _всех_ объектов созданных на диалоге.
Поэтому обработка QEvent::Paint будет также отрабатывать для всех объектов.
Поэтому нужно убрать ваш foreach и вставить проверку для каждого типа в отдельности.
И держать limDate, который используется только для QDateEdit как минимим неразумно.
Вызывать update() из paintEvent тоже неразумно, т.к. порождается новый QEvent::Paint.
Вообщем у вас получился hack причём _очень_ тяжелый для Qt.
Записан

Qt 5.11/4.8.7 (X11/Win)
fuCtor
Гость
« Ответ #2 : Апрель 28, 2010, 07:50 »

Старался сделать форму ввода с подсвечиваемыми полями:
http://www.prog.org.ru/topic_13273_0.html

Все работает хорошо, но при постоянном перерисовывании окна загрузка процессора возрастает до 50%. Как-то не хорошо получается. Форма ввода достаточно большая- до 30 полей.

Как правильней сделать, чтобы и поля выделялись, и процессор зря не нагружался?

Код такой:
Код:
bool mem_new_phpDialog::eventFilter(QObject *o, QEvent *e)
{
    QDate limDate;
    limDate.setDate(1900, 1, 1);

    if(e->type() == QEvent::Paint)
    {
        if(o->property("requiredField").toBool())
        {
            QWidget * w = dynamic_cast<QWidget *>(o);
            if(w && w->parentWidget()) {
                w->parentWidget()->update(QRect(w->pos(), w->size()).adjusted(-2, -2, 2, 2));
            }
        } else {
            QPainter p(qobject_cast<QWidget *>(o));
            QPen pen_;
            pen_.setWidth(1);
            pen_.setColor(QColor(255, 183, 183)); // Set border color
            p.setPen(pen_);
            p.setRenderHint(QPainter::Antialiasing);

            bool ready_ = true;

            foreach(QObject * obj, o->children())
            {
                if(obj->property("requiredField").toBool()) // Check widget
                {

                    if(
                            (obj->inherits("QLineEdit") && obj->property("text").toString().isEmpty()) ||
                            (obj->inherits("QComboBox") && obj->property("currentText").toString().isEmpty()) ||
                            (obj->inherits("QComboBox") && obj->property("currentText").toString().toLower() == tr("- не вказано -")) ||
                            (obj->inherits("QDateEdit") && obj->property("date").toDate() <= limDate) ||
                            (obj->inherits("QGroupBox") && obj->property("objectName").toString() == "gbSex" && ui->rbUnknown->isChecked())
                            )
                    {
                        ready_ &= false;
                        QWidget * w = dynamic_cast<QWidget *>(obj);
                        if(w)
                        {
                            QRect r(w->pos(), w->size());
                            p.drawRect(r.adjusted(-1, -1, 1, 1));
                        }
                    }
                }
            }
        }
    }
    return QDialog::eventFilter(o, e);
}

С Qt только начинаю, так что извиняюсь, если вопрос примитивный...Улыбающийся

Код мой, но не обратил внимание на нагрузку сначала.

Убери кусок
Код
C++ (Qt)
           QWidget * w = dynamic_cast<QWidget *>(o);
           if(w && w->parentWidget()) {
               w->parentWidget()->update(QRect(w->pos(), w->size()).adjusted(-2, -2, 2, 2));
           }
 
и вместо установки фильтра на контейнер и на поля, конекть сигнал об изменении содержимого поля со слотом Update() контейнера и будет все нормально тогда. Но фильтр на контейнера должен оставаться. У себя уже исправил.
Записан
radislav72
Гость
« Ответ #3 : Апрель 28, 2010, 10:37 »

Большое спасибо за подсказки, все работает хорошо... Все-таки без опыта работы в Qt самому разбираться со всем трудоемко, а так, на форуме- намного быстрее получается.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.359 секунд. Запросов: 23.