Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Qt 4.3.1 [Прилипание окна как у Winamp] 
:(
    Опции темы
SABROG
Дата 18.8.2007, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Думал все будет легко, алгоритм ясен. Но не получается, Trolltech предупредили, что вызывать setGeometry внутри moveEvent, resizeEvent нельзя, т.к. будет бесконечная рекурсия. Ну конец то у нее есть - краш, это я уже выяснил.

Но дело в том, что я поставил специальные проверки, чтобы избежать подобной рекурсии. По логике, если граница правой рамки окна входит в 5 пиксельную зону (у меня 20 для удобства) перед правой границей робочего стола, то мы просто из ширины экрана вычитаем размер нашего окна и это и будет новая позиция X. Поэтому, если координата X границы правого окна программы равна ширине экрана, то значит программа уже на своей месте и setGeometry не требуется. Интересность еще в том, что для нижней границы окна, когда идет рассчет по Y - все работает. Ну за исключением бага с возможностью изменить ширину окна потащив за верхнюю границу заголовка окна. Тут тогда и координаты окна меняются и высота его меняется, в итоге это приводит к тому, что увеличить высоту окна можно, а вот уменьшить уже нет. Ну думаю ладно, если вычисления по Y работают, то почему по X не пашут. Вот код для приклеивания окна к правому краю:

Код

void TForm::moveEvent(QMoveEvent *event)
{
    int _x = event->pos().x(), _y = event->pos().y();
    if ((_x+width()) >= (QApplication::desktop()->width()-20) && (_x+width()) !=  QApplication::desktop()->width())
    {
       _x = QApplication::desktop()->width() - width();
         qDebug() << "x():" << event->pos().x() << " y():" << event->pos().y() << " _x: " << _x << " _y:" << _y << " width():" << width() << " height():" << height() << " Dwidth():" << QApplication::desktop()->width() << " Dheight():" << QApplication::desktop()->height();
         setGeometry(_x, _y, width(), height());
    }    
}


А это то, что я вижу в логе:

Код

[18.08.07 19:12:02] [D] x(): 300  y(): 157  _x:  316  _y: 157  width(): 960  height(): 768  Dwidth(): 1280  Dheight(): 1024 
[18.08.07 19:12:02] [D] x(): 312  y(): 134  _x:  316  _y: 134  width(): 960  height(): 768  Dwidth(): 1280  Dheight(): 1024 
[18.08.07 19:12:02] [D] x(): 312  y(): 111  _x:  316  _y: 111  width(): 960  height(): 768  Dwidth(): 1280  Dheight(): 1024 
[18.08.07 19:12:02] [D] x(): 312  y(): 88  _x:  316  _y: 88  width(): 960  height(): 768  Dwidth(): 1280  Dheight(): 1024 
[18.08.07 19:12:02] [D] x(): 312  y(): 65  _x:  316  _y: 65  width(): 960  height(): 768  Dwidth(): 1280  Dheight(): 1024 
[18.08.07 19:12:02] [D] x(): 312  y(): 42  _x:  316  _y: 42  width(): 960  height(): 768  Dwidth(): 1280  Dheight(): 1024 
[18.08.07 19:12:02] [D] x(): 312  y(): 19  _x:  316  _y: 19  width(): 960  height(): 768  Dwidth(): 1280  Dheight(): 1024 
[18.08.07 19:12:02] [D] x(): 312  y(): -4  _x:  316  _y: -4  width(): 960  height(): 768  Dwidth(): 1280  Dheight(): 1024 
... и т.д. до краша


Отсюда видно, что изначально в setGeometry передается правильно. Но при следующем входе в moveEvent видно, что координаты искажены, хрен бы с иксом, так вот как меняется Y я ума не приложу. Сам я его нигде не вычитаю и шаг какой-то странный - 23. Dwidth и Dheith - ширина/высота рабочего стола.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
nickless
Дата 18.8.2007, 22:39 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



SABROG,
Попробуй вместо setGeometry(...) вызвать move(_x, _y), у меня так работает, правда в KDE smile 

А вообще можно реимплементировать QWidget::event() и делать там всё как QWidget, но позицию изменять заранее как надо, тогда оно будет лучше работать, потому что окно сразу передвинется куда нужно, а не будет прыгать как сейчас.


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
SABROG
Дата 19.8.2007, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Спасибо, действительно move() отрабатывает нормально. Вопрос решен.

Реализовал так, учитывая все известные баги это оптимальный вариант:

Код

void TForm::moveEvent(QMoveEvent *event)
{
    int _x = x(), _y = y(), newPosX = -1, newPosY = -1, snapFactorX = QApplication::desktop()->width()/30, snapFactorY = QApplication::desktop()->height()/30;
    if (_x > event->oldPos().x() && (_x+width()) >= (QApplication::desktop()->width()-snapFactorX) && (_x+width()) <  QApplication::desktop()->width())
    {
     newPosX = QApplication::desktop()->width() - width();
    }
    else if (_x < event->oldPos().x() && _x <= snapFactorX && _x > 0)
    {
     newPosX = 0;
    }
    if (_y > event->oldPos().y() && (_y+height()) >= (QApplication::desktop()->height()-snapFactorY) && (_y+height()) <  QApplication::desktop()->height())
    {
     newPosY = QApplication::desktop()->height() - height();
    }
    else if (_y < event->oldPos().y() && _y <= snapFactorY && _y > 0)
    {
     newPosY = 0;
    }
    if (newPosX != -1 || newPosY != -1)
    {   
         if (newPosX != -1)
         {
             _x = newPosX;
             newPosX = -1;
         }
         if (newPosY != -1)
         {
             _y = newPosY;
             newPosY = -1;
         }
         move(_x, _y);
    }   
}


Это сообщение отредактировал(а) SABROG - 19.8.2007, 11:47


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0646 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.