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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Как поймать событие окончания изменения размеров окна?  (Прочитано 17078 раз)
sint
Гость
« : Январь 29, 2008, 13:26 »

Добрый день.

У меня такая проблема: необходимо отловить событие изменения размеров QWidget с помощью мыши. А трудность в том, что это событие должно отработать только один раз (в момент отпускания пользователем мыши). В виду того, что при этом производятся достаточно тяжелые процессы, переопределение resizeEvent здесь не подходит (отрабатывается многократно, как я понял по таймеру). Решение со временной переменной так же  подошло, т.к. не смог определить какое из resizeEvent является последним.
Уперся в то, что при нажатии или отпускании левой кнопки мыши, к примеру, при находении последнего в нижнем углу окна, (курсор типа Qt::SizeFDiagCursor), не выбрасывается вообще никакого события (включая события  mousePressEvent  & mouseReleaseEvent).
Пытался переопределить event по такому же принципу QApplication или сделать эту форму как дочернюю (mdichild) - все тоже самое.

(Qt 4.3.3 + OpenSuse10.3/win32)

Спасибо.
Дмитрий.

---

Код:
class MyWidget: public QWidget {
 public:
  MyWidget(): QWidget(){ }
 protected:
  virtual bool event ( QEvent * event ){
   qDebug() << "MyWidget::event:" << event->type();
   return QWidget::event (  event );
  }
  virtual void resizeEvent ( QResizeEvent * e ){
   qDebug("MyWidget::resizeEvent");
   QWidget::resizeEvent(e);
  }
};

int main(int argc, char *argv[]){
   QApplication app(argc, argv);
   MyWidget main;
   main.show();
   return app.exec();
 }
« Последнее редактирование: Январь 29, 2008, 19:03 от pastor » Записан
WW
Гость
« Ответ #1 : Январь 29, 2008, 14:03 »

в ресайзевенте взводишь какой-нить служ. флажок, а в событии отпускания - кн. проверяешь его. если установлен - делаешь свое дело и сбрасываешь флаг.
Записан
sint
Гость
« Ответ #2 : Январь 29, 2008, 14:35 »

Это пробовалось с самого начала и, к сожалению, не подходит. Причина: как я отмечал ранее, я не могу определить какой из resizeEvent будет вызван последним (т.е. интересует именно тот resizeEvent, когда пользователь топустил мышку). При отпускании мыши никакое событие не гененируется. Вообще:-)
Записан
WW
Гость
« Ответ #3 : Январь 29, 2008, 15:58 »

что, даже mouseReleaseEvent ( QMouseEvent * event )  не генериться???
версия Qt?
Проверил. resizeEvent генериться равно один раз - конце процедуры изменения размера. А на счет mouseReleaseEvent - да, не генериться. Был не прав.
« Последнее редактирование: Январь 29, 2008, 16:26 от WW » Записан
sint
Гость
« Ответ #4 : Январь 29, 2008, 16:25 »

В том то и проблема. Если бы так было просто, я бы людей не беспокоил:-) Именно если рурсор мыши находится по бордюру окна (когда курсор меняется), эти события (mousePressEvent  & mouseReleaseEvent) не отрабатываются.
(Qt 4.3.3 + OpenSuse10.3/win32)

что, даже mouseReleaseEvent ( QMouseEvent * event )  не генериться???
версия Qt?
Записан
WW
Гость
« Ответ #5 : Январь 29, 2008, 16:26 »

ответил выше
Записан
ритт
Гость
« Ответ #6 : Январь 29, 2008, 16:34 »

вв, какая платформа и оконный манагер?
Записан
WW
Гость
« Ответ #7 : Январь 29, 2008, 16:41 »

под рукой ща винда
Записан
sint
Гость
« Ответ #8 : Январь 29, 2008, 17:31 »

Сейчас у меня тоже винда. Проверил - отрабатывается многократно. Как проверял: запускаю приложение  с консольным выводом из FAR (текст см. ниже). Хватаю мышкой за угол окна и начинаю тягать (изменять размер). Наблюдаю многократный вывод сообщения.
Qt 4.3.1 + WinXP SP2

Файл main.cpp

Код:
#include <QtGui>

class MyWidget: public QWidget {
 public:
  MyWidget(): QWidget(){ }
 protected:
  virtual void resizeEvent ( QResizeEvent * e ){
   qDebug("MyWidget::resizeEvent");
   QWidget::resizeEvent(e);
  }
};

int main(int argc, char *argv[]){
   QApplication app(argc, argv);
   MyWidget main;
   main.show();
   return app.exec();
 }

Файл sample.pro

Код:
TEMPLATE=app
SOURCES=main.cpp
target=./sample
CONFIG += qt warn_on debug console
DESTDIR=./

что, даже mouseReleaseEvent ( QMouseEvent * event )  не генериться???
версия Qt?
Проверил. resizeEvent генериться равно один раз - конце процедуры изменения размера. А на счет mouseReleaseEvent - да, не генериться. Был не прав.


*************************
Пользуйся тегами "Код" для оформления примеров кода! Я же писал уже про это в личку
« Последнее редактирование: Январь 29, 2008, 19:59 от pastor » Записан
WW
Гость
« Ответ #9 : Январь 29, 2008, 18:41 »

Еще раз проверил. Qt 4.3.2, Win, MSVC2k3. Резайзэвент срабатывает один раз. Проверить под 4.3.3. нет возможности.
Записан
ритт
Гость
« Ответ #10 : Январь 29, 2008, 19:20 »

вв, проверял этот же код? куда делал вывод дэбага?
у меня аналогичный код прилично спамит мессагами. одно "но" - в венде при изменении размеров окна (драгом) и перетаскивании окна блокируется большинство событий...подозреваю, что ты этим и обманулся

синт, с первым ресайзИвентом запусти таймер и сохрани старый сайз, последующие ресайзИвенты в серии игнорируй и отрабатывай только таймаут твоего таймера, в котором сравнивай старый и новый сайзы и обновляй старый сайз на новый, если они отличаются, в противном случае убивай таймер и запускай перерисовку (или что там у тебя такое медленное)
сейчас более умного ничего не посоветую...
Записан
sint
Гость
« Ответ #11 : Январь 29, 2008, 20:24 »

Спасибо большое. Я так пробовал - делал таймер на треть секунды неактивности мыши. Напоролся на другую проблему, которая заставила мне похоронить эту идею:
Все, что касается интерактивной работы - вроде бы этот подход работал нормально, но когда и имеются несколько окон и ПРОГРАММНО их надо перерисовать (я использую SpiderMontkey JavaScript для управления приложением) в короткий срок, то начинаются непонятки с этими таймерами  - несоблюдается последовательность. А бороться с потоками из за такой казалось бы по-началу мелочи морально не был готов. Это раз. А второе и самое главное - при программном управлении и перерисовки, допустим, десятка окон в цикле при решении проблемы "разруливания" их будут заметные тормоза.
Здесь самое обидное то, что не получается отличить программное изменение размеров от изменения посредством мыши (события мыши то не отрабатываются) :-(

А медленное у меня -  рисование карты во временный битмап. От этого и хотел избавиться.

Спасибо за помощь. Будем думать.

Насчет тегов - прошу прощения:-)

вв, проверял этот же код? куда делал вывод дэбага?
у меня аналогичный код прилично спамит мессагами. одно "но" - в венде при изменении размеров окна (драгом) и перетаскивании окна блокируется большинство событий...подозреваю, что ты этим и обманулся

синт, с первым ресайзИвентом запусти таймер и сохрани старый сайз, последующие ресайзИвенты в серии игнорируй и отрабатывай только таймаут твоего таймера, в котором сравнивай старый и новый сайзы и обновляй старый сайз на новый, если они отличаются, в противном случае убивай таймер и запускай перерисовку (или что там у тебя такое медленное)
сейчас более умного ничего не посоветую...
« Последнее редактирование: Январь 29, 2008, 20:28 от sint » Записан
ритт
Гость
« Ответ #12 : Январь 29, 2008, 20:42 »

отличить программное событие от юзверьского можно - читай доки по ивентам (спонтанус)
но настоящим решением было бы, конечно, избавление от тормозов отрисовки...
заюзай нити, посмотри QMapControl - решение обязано быть!

зы. было бы интересно взглянуть на твой проект
Записан
sint
Гость
« Ответ #13 : Январь 29, 2008, 20:58 »

Ой спасибо, добрый человек, за spontaneous. Выручил. Теперь можно таймеры обратно прикручивать.

Насчет проекта - не могу, извини. Слово дал.

отличить программное событие от юзверьского можно - читай доки по ивентам (спонтанус)
но настоящим решением было бы, конечно, избавление от тормозов отрисовки...
заюзай нити, посмотри QMapControl - решение обязано быть!

зы. было бы интересно взглянуть на твой проект
Записан
sint
Гость
« Ответ #14 : Январь 30, 2008, 00:41 »

Для простого окна решение с spontaneous прокатило, а вот для mdichild нет.
Как вариант меня пока устроил:
Код:
TRWidget*w = new TRWidget(this);
QMdiSubWindow *s = mdiArea->addSubWindow(w, Qt::SubWindow);
s->setOption(QMdiSubWindow::RubberBandResize);

отличить программное событие от юзверьского можно - читай доки по ивентам (спонтанус)
но настоящим решением было бы, конечно, избавление от тормозов отрисовки...
заюзай нити, посмотри QMapControl - решение обязано быть!

зы. было бы интересно взглянуть на твой проект
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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