Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: cresta от Июль 08, 2007, 15:31



Название: Ресайз окна без заголовка
Отправлено: cresta от Июль 08, 2007, 15:31
Добрый день.
Проблема с ресайзом окна.
Сделал окно без заголовка. Форму окна задаю в updateMask().
Для ресайза окна ставлю в правом нижнем углу label, и фильтрую его сообщения (MouseButtonPress, MouseMove, MouseButtonRelease).
При приеме сообщений от мыши вычисляю относительное перемещение и в соответствии с этим перемещением мыши меняю размер окна (resize()) и перезадаю новую маску для нового размера окна.
Если перемещения мыши не очень резкие, то всё ресайзится нормально.
Проблема возникает, если растянуть окно резко. После резкого изменения положения курсора последующие изменения его положения вызывают хаотическое перемещение окна по всему экрану и при этом окно принимает произвольные размеры.
Путем экспериментов выяснил, что проблема устраняется, если updateMask() вызывать не по MouseMove, а по MouseButtonRelease. т.е. один раз после завершения движения мыши.
Но при этом я лишаюсь наглядности процесса растяжения. т.е. окно меняет размер только после завершения движения мыши и отпускания кнопки.

Код:
    void gui::updateMask(){
        int         w = this->width();
        int         h = this->height();
        QBitmap     bm(w, h);
        bm.fill(Qt::color0);

        QPainter    p(&bm);
        p.setBrush(Qt::color1);
       
        mask->setPoint(1, w-3, 0);
        mask->setPoint(2, w, 3);
        mask->setPoint(3, w, h-3);
        mask->setPoint(4, w-3, h);
        mask->setPoint(5, 3, h);
        mask->setPoint(6, 0, h-3);
       
        p.drawPolygon( *(mask), FALSE, 0, 8 );
        this->setMask(bm);
    }

   
Я вот не пойму, что может тормозить или глючить в этой функции?

Посему вопросы:
1. как ускорить updateMask?
2. если нельзя ускорить, и надо таки отказаться от ресайза до отпукания кнопки мыши, то как нарисовать хотя бы на десктопе рамку, чтобы был виден размер, до которого изменится окно?
3. может здесь как-то поможет захват мышиных сообщений, чтобы фокус мыши был жестко задан для лейбла?


Название: Ресайз окна без заголовка
Отправлено: goer от Июль 08, 2007, 15:48
А если такой вариант:

По MouseButtonPress Ты запускаешь таймер и в timerEvent-е проверяешь текущее положение мыши и соответственно ему ресайзишь(апдейтишь) свое коно. По mouseRelease останвливаешь таймер.

У нас подобная шняга с таймерами юзается на ура в тех случаях когда мышинные события проглатываются.

Для справки: интервала в 100 мс вполне достаточно для апдейта.


Название: Ресайз окна без заголовка
Отправлено: cresta от Июль 08, 2007, 18:32
Решил проблему. Дело было в том, что новая ширина окна рассчитывалось как dialog->width() + delta, где delta - приращение относительно предыдущей ширины окна.

при быстром изменении положения курсора следующее сообщение MouseMove приходит раньше фактического изменения ширины окна, т.е ширина ещё dialog->width(), хотя рассчет начинается как будто ширина уже стала dialog->width() + delta. Отсюда ошибка.

Избавился от глюка путём перехода от рассчета приращения через ширину окна к рассчету приращения через абсолютные экранные координаты мыши. которые не зависят от ширины окна  и скорости обновления этой ширины.