Название: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 03:53 Описание алгоритма:
Если при перемещении или изменения размера окна расстояние между краем рабочего стола и окном меньше какого то значения, то перемещаем окно к тому краю. Создал наследника QWidget, переопределил методы resizeEvent и moveEvent, доступ к геометрии рабочего стола получал через QDesktopWidget().availableGeometry(). Понял, что применение алгоритма в resizeEvent и moveEvent плохая идея - вызывается бесконечная рекурсия, а других идей нет :( Как решить эту проблему? :) Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Bepec от Январь 14, 2014, 06:59 Просто посылайте сигнал при ресайзе, мовинге. А в принимаемом слоте уже рассчитывайте всё.
У меня аналогичный класс так и работает - у родителя перехватывается resize и move, которые посылают сигнал "прилипалкину". А там уже вызывается слот, который рассчитывает, учитывает состояние (прилип, не прилип) и перемещает. Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 07:45 Просто посылайте сигнал при ресайзе, мовинге. А в принимаемом слоте уже рассчитывайте всё. Только, наверное, стоит сказать, что connect нужно делать с Qt::QueuedConnection, иначе опять получишь рекурсию.У меня аналогичный класс так и работает - у родителя перехватывается resize и move, которые посылают сигнал "прилипалкину". А там уже вызывается слот, который рассчитывает, учитывает состояние (прилип, не прилип) и перемещает. Имхо, зарядить таймер будет проще. Кстати, в обработчиках событий за исключением таймерных в любом тулките нужно стараться избегать действий приводящих к генерации новых событий. Это аксиома) Название: Re: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 08:00 А можно подробнее насчет таймера? :)
Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 08:12 А можно подробнее насчет таймера? :) int QObject::startTimer ( int interval ) (http://doc.crossplatform.ru/qt/4.7.x/qobject.html#startTimer)Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Bepec от Январь 14, 2014, 08:19 Ну не знаю, в любом случае будет вызов слота и соединение.
Но принцип тот же. Что отделяем зёрна от плевел. Или ставим задачу в очередь (сигнал), или ставим таймер в очередь :D Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 08:37 Ну не знаю, в любом случае будет вызов слота и соединение. С чего это? Разве разговор шел про QTimer?Цитировать Но принцип тот же. Что отделяем зёрна от плевел. Или ставим задачу в очередь (сигнал), или ставим таймер в очередь :D Не всегда удобно, да и излишне для своих внутренних дел самому испускать и обрабатывать свои же сигналы.Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Bepec от Январь 14, 2014, 08:52 Тогда я тоже заинтересован. Как же тогда обрабатывать таймер?
Я вижу варианты: 1) проверочный цикл. 2) слот timerEvent. Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 10:22 2) слот timerEvent. Только это не слот, аКод и в выше приведённой ссылке есть пример. Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Bepec от Январь 14, 2014, 10:31 Каюсь, глаз замылился :)
Тоже вариант. С таймером быстрее, но тут решать нужно самому. Кому то понятнее сигналы, кому то таймер. Хотя попробовать надо как нить. Ни разу не использовал его так. Название: Re: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 11:53 Для максимального приближения к реальной задачи написал окно без системной рамки - MovableWindow.
От него отнаследовался и в наследнике реализовал вот такой алгоритм. Нормально? :) Код
UPDATE. Убрана лишняя проверка и уничтожение "левых" таймеров Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 12:11 В AttachableWindow::timerEvent() не мешало бы сделать проверку на QTimerEvent::timerId () == timerId и
killTimer( timerId ) делать там же, а то пока не отпустишь кнопку таймер будет срабатывать. Название: Re: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 12:30 В AttachableWindow::timerEvent() не мешало бы сделать проверку на QTimerEvent::timerId () == timerId и killTimer( timerId ) делать там же, а то пока не отпустишь кнопку таймер будет срабатывать. Такой проверки хватит? :) Код
Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 12:32 А зачем же в этом случае прибивать таймер ???
Прибивать его следует только при QTimerEvent::timerId () == timerId. Название: Re: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 12:36 А зачем же в этом случае прибивать таймер ??? Прибивать его следует только при QTimerEvent::timerId () == timerId. Значит неправильно понял вашу идею :) А смысл прибивать таймер, если его и так прибьет после того как будет отпущена мышь? :) Таймер ведь работает пока зажата кнопка мыши :) Название: Re: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 12:38 Не понравилась мне реализация с наследованием, поэтому переписал :)
Название класса кажется не удачным :-\ Код
Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 12:39 А смысл прибивать таймер, если его и так прибьет после того как будет отпущена мышь? :) Согласен)Таймер ведь работает пока зажата кнопка мыши :) Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Igors от Январь 14, 2014, 13:06 А если по-народному?
Код
Название: Re: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 13:15 Igors, интересное решение :)
Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Igors от Январь 14, 2014, 13:22 На нормальном ОС даже не нужно отслеживать драг - окно как бы "упирается", сдвинуть дальше его пользователь не может. Но на чмошном Вындоуз возникает неприятный эффект "мельтешения" :'(
Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 14:01 На нормальном ОС даже не нужно отслеживать драг - окно как бы "упирается", сдвинуть дальше его пользователь не может. Но на чмошном Вындоуз возникает неприятный эффект "мельтешения" :'( Наверное нужно всё-таки говорить не про ОС, а оконный менеджер.В случае ТС оный не используется вовсе, так что только ручками) Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Igors от Январь 14, 2014, 17:36 Наверное нужно всё-таки говорить не про ОС, а оконный менеджер. Хмм... я полагал что FrameLess вообще не заслуживает обсуждения - ведь там никакого реентера нет, зачем совать таймер? Ну ладно, примерчик в аттаче (была заготовка для драга, добавил отсечки)В случае ТС оный не используется вовсе, так что только ручками) Вспоминая недавнюю тему - не лучше ли было иметь этот сервис "внешним", не загружая код рабочих окон ? :) Название: Re: Прикрепление окна к краю рабочего стола Отправлено: GreatSnake от Январь 14, 2014, 17:41 Хмм... я полагал что FrameLess вообще не заслуживает обсуждения - ведь там никакого реентера нет, зачем совать таймер? Согласен, через postEvent() красивее)Цитировать Вспоминая недавнюю тему - не лучше ли было иметь этот сервис "внешним", не загружая код рабочих окон ? :) Хм... чего-то не понял про что речь?Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Igors от Январь 14, 2014, 18:08 Хм... чего-то не понял про что речь? Ну вот написан какой-то код (любой из вариантов выше, здесь не суть). Как его использовать? Когда "все с нуля" эта проблема не чувствуется - захотел создал новый класс, почему нет. А вот когда уже что-то наработано - ой как не хочется это ворошить, а если еще хоть часть кода не своя... Вот если gil9red призадумается как сделать это "easy to use" :)Название: Re: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 23:09 Хм... чего-то не понял про что речь? Ну вот написан какой-то код (любой из вариантов выше, здесь не суть). Как его использовать? Когда "все с нуля" эта проблема не чувствуется - захотел создал новый класс, почему нет. А вот когда уже что-то наработано - ой как не хочется это ворошить, а если еще хоть часть кода не своя... Вот если gil9red призадумается как сделать это "easy to use" :)Подумаю, но не обещаю, что сделаю :D Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Old от Январь 14, 2014, 23:24 Подумаю, но не обещаю, что сделаю :D Ну так вы уже придумали AddAttachable. Объект этого класса можно использовать вне перемещаемого объекта: есть готовый виджет, стало нужно что бы он начал прилипать - добавили объект класса AddAttachable и привязали к нему виджет.Внимательно посмотрите на условие, паранойя ли? ;) [window = 0; activate = true] -> какой результат? Код
Название: Re: Прикрепление окна к краю рабочего стола Отправлено: gil9red от Январь 14, 2014, 23:53 Подумаю, но не обещаю, что сделаю :D Ну так вы уже придумали AddAttachable. Объект этого класса можно использовать вне перемещаемого объекта: есть готовый виджет, стало нужно что бы он начал прилипать - добавили объект класса AddAttachable и привязали к нему виджет.Внимательно посмотрите на условие, паранойя ли? ;) [window = 0; activate = true] -> какой результат? Результат будет true, только тогда, когда обе переменные имеют значение false (или 0) - не заметил - косяк :)Код
Надо бы условие поменять на логическое "или" (||) :) А паранойя, потому что, в eventFilter прописано условие создания таймера и timerEvent не должен случиться, только если его не вызовут другие таймера :) Название: Re: Прикрепление окна к краю рабочего стола Отправлено: Old от Январь 15, 2014, 00:00 А паранойя, потому что, в eventFilter прописано условие создания таймера и timerEvent не должен случиться, только если его не вызовут другие таймера :) В таких случаях принято ставит assert. |