Название: (РЕШЕНО) Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 22, 2015, 22:00 Есть бесконечная сцена, которая видна в стандартном прямоугольном QGraphicsView. Пользователь видит скроллы и может менять положение вьюпорта на сцене.
Изменение положения скроллов у меня ловится, и по нему взводится флаг необходимости сохранения сцены, поскольку изменилось положение вьюпорта, которое сохраняется в файле сцены. Тут всё было бы хорошо, если бы не одна неожиданность - Qt зачем то двигает 1 скролл (не выяснил какой - не интересно), уже после того, как отработал мой конструктор главного окна, появилось само окно, загрузилась и нарисовалась сцена, и я сбросил все флаги изменений. В результате получается, что сцена после запуска всегда оказывается изменена, и надо её сохранять. Хотя после начального запуска и загрузки сцена должна считаться неизмененной. Я это обошел с помощью простого хака - флаг, который установлен в конце конструктора, проверяется в приемнике сигнала сдвига скролла, и один сигнал скролла игнорируется, после чего флаг сбрасывается. Так всё работает как необходимо. Но. Это у меня сейчас Qt 4.7, и похоже, что это баг. На это намекает сигнал об изменении только 1-го скролла, хотя у моей сцены их 2, а также отсутствие какой-либо разумной необходимости его менять, поскольку я сам нигде после загрузки сцену не меняю до тех пор, пока это не сделает уже пользователь. И как это работает в Qt 5.x? Может там баг уже исправлен? Кто может проверить? Если кто делает что-нибудь похожее?? Сцену бесконечного размера с просмотром через окно в редакторе - в конструкторе класса главного окна надо накидать на неё чего-нибудь, у обоих скроллов соответствующего QGraphicsView сигналы valueChanged(int) должны быть привязаны к слоту класса главного окна, в котором выводится qDebug << счетчик; и этот счетчик сброшен в 0 в самом конце конструктора класса главного окна. Что покажет счетчик после запуска и отработки конструктора? Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Bepec от Февраль 22, 2015, 22:17 Ну как бы логично всё. Ты всё создал, появляется окно, нарисовалась сцена, испускается 2 сигнала изменения скроллов - горизонтального и вертикального :)
Но на деле тебе проще выводить в дебаг отправителя сигнала и мониторить состояние полосочек) Сразу увидишь вредителя. PS если выложишь проект, я могу позырить. PPS нет, сам я не могу выложить сцену, привязаться к сигналам и мониторить - мне лень и мне нужен проект :D Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 22, 2015, 23:58 Лишний сигнал приходит ОДИН, хотя скроллов ДВА. И сигналы при изменении сцены приходят РАНЬШЕ, когда я сцену загружаю и отрисовываю. В эти моменты приходят два сигнала, как положено. И когда MainWindow::show() вызываю, тоже приходят положенные два сигнала. Но потом, когда я уже всё закончил делать, почему-то приходит ЕЩЕ ОДИН. ??? Ну я бы согласился еще как-то, что могут два сигнала прийти, мало ли какая-то отрисовка внутри Qt потом произошла. Хотя зачем, если уже всё отрисовано, и я ничего со сценой не делаю? Но приходит только один сигнал. Я в полном недоумении.
Отправителя этого сигнала не вижу особого смысла в дебаге выводить - я в дебаге поймал этот сигнал, вижу стек, это сплошь Qt-шные потроха. В стеке вызовов самый нижний назывался что-то вроде qt_internals... Ну посмотрю я, кто отправитель - и что с ним делать? Проект не пришлю, приватная разработка, несколько ноу-хау. Этот глюк я обошел, но мне не ясно, что будет в версиях Qt 5.x. Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Bepec от Февраль 23, 2015, 00:24 Подытожим - в проблеме не разобрались, считаем это багом, проверять не хотим :)
PS тему можно удалять, никакой информации она не несёт. Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 23, 2015, 00:34 Тема содержит вопрос/просьбу к тем делает что-то похожее на более новых версиях Qt - проверить как они ведут себя в похожей ситуации. Поэтому ничего удалять не надо.
Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Old от Февраль 23, 2015, 08:05 Тема содержит вопрос/просьбу к тем делает что-то похожее на более новых версиях Qt - проверить как они ведут себя в похожей ситуации. Поэтому ничего удалять не надо. Да уже поставили бы себе пятерку и проверили на ней. :)У меня сейчас как правило, установлены Qt 5.X, 4.8.6, 4.7.X. В разных проектов используются разные версии. Все спокойно уживается и используется. Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Igors от Февраль 23, 2015, 12:41 Но потом, когда я уже всё закончил делать, почему-то приходит ЕЩЕ ОДИН. Что значит "почему-то"?. Точка прихода есть, стек вызовов есть, значит в отладчике должно быть видно "почему"Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: xokc от Февраль 23, 2015, 14:03 Кто может проверить? Если кто делает что-нибудь похожее?? Сцену бесконечного размера с просмотром через окно в редакторе - в конструкторе класса главного окна надо накидать на неё чего-нибудь, у обоих скроллов соответствующего QGraphicsView сигналы valueChanged(int) должны быть привязаны к слоту класса главного окна, в котором выводится qDebug << счетчик; и этот счетчик сброшен в 0 в самом конце конструктора класса главного окна. Что покажет счетчик после запуска и отработки конструктора? Проект не пришлю, приватная разработка, несколько ноу-хау. Какая интересная позиция: сделайте, кто-нибудь за меня тестовый проект и проверьте на своем комплекте. А то у меня проблема, но нет на это времени, мне лень... (нужное подчеркнуть). Даже интересно найдутся добровольцы? А то у меня тоже есть ряд проблем, которые стоило-бы проверить, но мне лень.Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Igors от Февраль 23, 2015, 14:46 Какая интересная позиция: сделайте, кто-нибудь за меня тестовый проект ... Он очень занят, ему надо "поднимать проект", там тонна работы. А другим не надо, они все равно фигней маются, вот пусть обслуживают "пахаря". Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Bepec от Февраль 23, 2015, 14:49 Тссс ) а темку счас реально надо удалять :D
Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 23, 2015, 14:51 Что значит "почему-то"?. Точка прихода есть, стек вызовов есть, значит в отладчике должно быть видно "почему" В стеке видны только Qt-шные вызовы. 78 штук. Ни одного моего. Можно конечно, полезть по ним, но пока до этого руки не дошли. сделайте, кто-нибудь за меня тестовый проект Этого я не прошу - просьба к тем, у кого есть уже аналогичный проект. Несколько строк в него вставить.Тссс ) а темку счас реально надо удалять :D не надо - просто кто не может ничем помочь, пусть не реагирует Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 23, 2015, 15:25 Ну посмотрел я стек вызовов. Уже после того, как отработала инициализация ui, после того, как созданы сцены, на сцены помещены айтемы, все нужные объекты уже существуют, выведены на экран и работают - начинается тряска. Приложение запостило event, вызывающий дальше обновление всего интерфейса. И при этом обновлении есть в середине вызов centerView(lastCenterPoint), в котором якобы горизонтальный скроллбар смещается. Хотя никто и ничто его на самом деле не смещает и визуально никакого смещения не видно. Вертикальный при этом никуда не смещается, и от него сигнала нет. Ошибка возникает при округлении qreal до int, поскольку косяк в этой строке (функция void QGraphicsView::centerOn(const QPointF &pos)):
Цитировать horizontalScrollBar()->setValue(int(viewPoint.x() - width / 2.0)); - все наклонные типа qrealа в числах там 32378.0-845/2.0 = 31955.5 - вот эти 0.5 и дают ошибку и что забавно, для вертикального скролла такое вычисление не вызывается (хотя в коде есть), и у него ошибка не возникает ЗЫ, посмотрел исходники Qt 5.4 в сети - там та же фигня. Вот теперь ветку можно закрыть. Но удалять не надо. Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 25, 2015, 21:00 Поторопился я объявить этот глюк решенным. Нифига. Даже при всех нормальных значениях Qt умудряется сдвигать вьюпорт на 1 пиксел после всех инициализаций и загрузок. То есть, мой хак работает, но не всегда.
Я попытался сбросить признак изменения сцены после того, как приложение входит в eventLoop, стандартным приемом с однократным таймером. ТОЖЕ НИФИГА. Таймер срабатывает, признак сбрасывается, но вьюпорт сдвигается уже ПОСЛЕ этого. >:( Код: ...... это конец конструктора MainWindow и вывод в консоль: Цитировать reset set set ППЦ. Как это побороть - не знаю пока. Нет идеи... :-\ Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 25, 2015, 21:28 ВАХ!
Код: onstart.singleShot( 1, this, SLOT(started()) ); Цитировать set set reset Разве где-то описано, что при 0 времени для singleShot таймер сработает ДО входа в eventLoop, а при не 0 - ПОСЛЕ?? Хотя может быть просто за 1 мс оно успело сморозить и смещение, и обработать сигнал о нём. Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Bepec от Февраль 25, 2015, 22:43 написано что если значение равно 0, то идёт вызов функции :) Причем в документации по таймеру даже.
Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 25, 2015, 22:56 В описании QTimer про 0 вот что написано:
Цитировать As a special case, a QTimer with a timeout of 0 will time out as soon as all the events in the window system's event queue have been processed. То есть, сработает так скоро, как были обработаны все события в очереди оконной системы. А в описании singleShot( time, object, slot ) про время вообще ни слова, очевидно тоже самое, что у таймера с заданным временем. Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Bepec от Февраль 25, 2015, 23:04 Ну я лично в исходниках видел
Код: if == 0 Хотя как обычно добавлю - новые версии могли измениться, но врядли :) Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 25, 2015, 23:06 Ну я лично в исходниках видел Код: if == 0 Хотя как обычно добавлю - новые версии могли измениться, но врядли :) Хе, так эта проверка и вызов могут (точнее, судя по описанию должны) быть ПОСЛЕ того, как отработают события оконной системы. И таймаут запускается ПОСЛЕ этого. Разумеется, перед запуском всегда будет проверка времени на 0, ибо если 0, то какой смысл таймер дергать, можно сразу вызывать. Но к обработке событий это не имеет никакого отношения. Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Bepec от Февраль 26, 2015, 01:08 Эммм в статическом методе SingleShot, я имею в виду. Сразу при вызове) Мгновенно) бесповоротно :D
Название: Re: Лишнее изменение скролла после работы конструктора в других версиях Qt Отправлено: Гурман от Февраль 26, 2015, 01:59 Значит недокументированное поведение, которое противоречит интуитивно ожидаемому по смежным описанным в документации функциям. Нехорошо это...
|